Примените команду awk ко всем файлам в каталоге

#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, которые разделяют элементы с нулевыми значениями (запрещено в именах файлов) вместо новых строк (не запрещено), но если ваш скрипт не должен запускаться в действительно враждебной среде, это, вероятно, того не стоит.