Извлечение строк с использованием разной информации в разных столбцах

Поскольку вы не указали переменную в:

echo $A

он подлежит разделению и объединению. Первый шаг — расширение содержимого переменной:

echo a $'\n' b $'\n' c--, где биты $'\n'представляют фактические символы новой строки.

Затем различные части разбиваются на $IFS, в результате чего:

echo a b c

Затем, поскольку нет подстановочных знаков для создания дополнительных имен файлов, строки передаются в echo.

Когда вы заключаете переменную в кавычки с помощью echo "$A", вы запрещаете разделение и подстановку.

См. изменение самостоятельно, если вы модифицируете IFS:

oIFS=$IFS
IFS=
echo $A
IFS=$oIFS
3
10.03.2021, 21:53
4 ответа

Использование awkи обработка входного файла только один раз:

awk 'min[$3, $5]!=""{ if(min[$3, $5]>$6){ line[$3, $5]=$0; min[$3, $5]=$6}; next }
                    { min[$3, $5]=$6; line[$3, $5]=$0 }
END{ for(x in line) print line[x] }' infile

К "сохранять строки с равными минимальными значениями" в 6 столбце:

awk 'min[$3, $5]!=""{ if(min[$3, $5] >$6){ line[$3, $5]=$0; min[$3, $5]=$6 };
                      if(min[$3, $5]==$6){ line[$3, $5]=line[$3, $5] ORS $0 }; next
                    }
                    { min[$3, $5]=$6; line[$3, $5]=$0 }
END{ for(x in line) print line[x] }' infile
4
18.03.2021, 22:26

выводится в порядке, отличном от предложенного вами, поэтому, если порядок не критичен, это работает:

sort -s -k3,3 -k5,5 -k6,6n < in | perl -ane 'print unless $seen{$F[2]}{$F[4]}++' > out

Если исходный порядок должен быть сохранен, вы можете запустить

nl < in | sort -s -k4,4 -k6,6 -k7,7n | perl -ane 'print unless $seen{$F[3]}{$F[5]}++' | sort -k1,1n | cut -f2- > out

Однако даже ваш выходной образец не сохраняет исходный порядок(grep 4ch[9b]_A_001во входных и выходных образцах, и вы увидите ).

0
18.03.2021, 22:26
sort -t$'\t' -k3,3 -k5,5 -k6n,6 file | awk -F\\t '!seen[$3,$5]++'

Главное, что sortиспользуется для числовой сортировки поля 6 -следующее также будет работать:

sort -t$'\t' -k6n,6 file | awk -F\\t '!seen[$3,$5]++'

Однако вывод не будет сгруппирован по столбцам 3 и 5. awkиспользуется для печати первой строки, содержащей уникальную пару столбцов 3/5. "$(printf '\t')"можно использовать вместо $'\t'в оболочке, которая не поддерживает строки $'...'C.

awk обрабатывает файл дважды, чтобы сохранить тот же порядок, что и при вводе, а также сохранить строки с одинаковыми минимальными значениями:

awk '
FNR==NR {if (min[$3,$5]=="" || $6<min[$3,$5]) min[$3,$5]=$6; next} $6==min[$3,$5]
' file file
2
18.03.2021, 22:26

Сawk

FNR==NR && !seen[$3,$5]++ {val[$3,$5]=$6}
FNR==NR && seen[$3,$5] {if ($6<val[$3,$5]) {val[$3,$5]=$6} }
 
NR!=FNR && val[$3,$5]==$6

Выполнить с

awk -f script.awk input input

Что он делает?

Создать псевдо -многомерный массив , используя столбцы 3 и 5 в качестве индексов и

  1. если такого элемента нет, получить значение столбца 6
  2. если есть такой элемент, сравнить значения со столбцом 6 и выбрать меньшее
  3. Затем повторно просмотрите файл и выберите каждую строку, в которой индексы массива соответствуют столбцам 3 и 5, а значение столбца 6 соответствует элементу массива.

Проходит дважды по файлу, но занимает очень мало оперативной памяти. Сортировка такая же, как во входном файле.

4
18.03.2021, 22:26

Теги

Похожие вопросы