Сравнение awk с использованием массивов

Я соглашаюсь с l0b0 grep, плохая идея здесь, но так или иначе, здесь объяснение проблемы и обходное решение. На Солярисе 10 и более старый, /bin/sh устаревшая оболочка, которая не должна использоваться ни для чего кроме запущения скриптов прежней версии. Действительно необходимо использовать ksh, bash или /usr/xpg4/bin/sh вместо этого.

Первопричина здесь ^ используемый, чтобы быть исходным способом указать канал в ранние времена Unix. Солярис /bin/sh наследованный эта archaelogical функция.

Обходное решение затем довольно просто, просто выйдите из каре один из этих путей:

ls /a |grep \^[0-9]

или

ls /a |grep "^[0-9]"

или

ls /a |grep '^[0-9]'
4
29.07.2015, 15:14
3 ответа

Я не понимаю, зачем вам делать это с помощью одной команды awk , то, что у вас есть, кажется совершенно нормальным. Во всяком случае, вот один способ:

$ awk -F, '(max[$18]<$21 || max[$18]==""){max[$18]=$21;line[$18]=$0}
            END{for(key in line){print line[key]}}' file
6598,6598,0,1,,1,0,1,1,0,0,0,1,0,0,0,0,1390,1390,,0.730000,
1297,1297,0,0,,0,0,1,0,0,0,0,0,1,0,1,0,1707,1707,,7.000000,
6553,6553,0,1,,1,0,1,1,0,0,0,0,1,0,1,0,4326,4326,,9.000000,

Идея очень проста. У нас есть два массива, max имеет 18 долларов США в качестве ключа и 21 доллар США в качестве значения. Для каждой строки, если сохраненное значение для $ 18 меньше, чем $ 21 или если нет значения, сохраненного для $ 18 , то мы сохраняем текущую строку ( $ 0 ) как значение для $ 18 в строке массива . Наконец, в блоке END {} мы печатаем array line .

Обратите внимание, что приведенный выше сценарий обрабатывает $ 18 как строку. Следовательно, 001 и 1 будут считаться разными строками.

8
27.01.2020, 20:46

Вы можете попробовать следующее awk :

awk -F"," '{ if (max[$18] < $21) { max[$18] = $21; x[$18] = NR; } z[NR] = $0; } END { for (i in x) print z[x[i]]; }' file

Он использует 3 массива max и x с ключами столбца $ 18 и z с номерами строк ключей. В max мы храним максимальные значения, в x мы храним номер строки, содержащей максимальное значение, а в z каждую строку в файле. В блоке END для каждого ключа в массиве x мы печатаем значение z [x [i]] .
Это решение не подходит для больших файлов, поскольку оно считывает файл целиком в память.

1
27.01.2020, 20:46

Использование uniq вместо awk может быть немного быстрее:

sort -t, -k18,18nr -k21,21nr | uniq -s39 -w4
4
27.01.2020, 20:46

Теги

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