#awk
Вопрос:
Я новичок в awk и хотел бы применить простую команду awk ко всем файлам в каталоге и получить результат для каждого файла отдельно. Файлы разделены табуляцией, и мне просто нужно суммировать каждое значение в столбце 11 и распечатать результат отдельно для каждого файла. Я попробовал следующий код, но он не работает.
for i in *;
do
awk -F 't' '{sum = $11} END {print sum} "$i"'
done
Спасибо!
Ответ №1:
Вы можете использовать это gnu awk
:
awk -F 't' '{sum = $11} ENDFILE {print FILENAME ":", sum; sum=0}' *
ENDFILE
блок будет запущен в конце обработки для каждого файла, в котором мы печатаем имя файла и сумму.
Если у вас нет gnu awk
, то используйте это:
awk -F 't' 'FNR==1 {if (sum) print fn ":", sum; sum=0; fn=FILENAME}
{sum = $11} END {print fn ":", sum}' *
Комментарии:
1. @PaulaO: Вы нашли что-нибудь неправильное в этом ответе?
Ответ №2:
Похоже, у вас в цитировании оболочки есть простая опечатка; это должно сработать:
for f in *; do awk -F 't' '{sum = $11} END {print sum}' -- "$f"; done
( --
это необходимо только для защиты от одного из имен файлов, начинающихся с дефиса; переменная, называемая i
обычно целочисленной по старому соглашению Фортрана, поэтому использовать ее для строки немного извращенно); или альтернативно
ls | while read -r f; do awk -F 't' '{sum = $11} END {print sum}' -- "$f"; done
если вы хотите избежать риска превышения предела длины командной строки (которая велика, но конечна в текущих системах), хотя это произойдет, если в ваших именах файлов появятся новые строки (почему?!..).
Если вы хотите сделать все за один вызов Awk, вы можете отслеживать файлы, используя FNR (количество записей внутри файла) и ИМЯ ФАЙЛА:
awk -F 't' 'FNR==1 {if (f) print sum; sum = 0; f = FILENAME} END {print sum} {sum = $11}' -- *
или альтернативно (может вызывать awk один или несколько раз)
ls | xargs awk -F 't' 'FNR==1 {if (f) print sum; sum = 0; f = FILENAME} END {print sum} {sum = $11}' --
с теми же оговорками, что и выше.
Вы можете защититься от новых строк в именах файлов, отказавшись от POSIX и используя GNUisms, которые разделяют элементы с нулевыми значениями (запрещено в именах файлов) вместо новых строк (не запрещено), но если ваш скрипт не должен запускаться в действительно враждебной среде, это, вероятно, того не стоит.