$ awk '{ c = 0 } { for (i = 2; i <= NF && c == 0; ++i) { c += ($i != 0) } } c > 0' foo.txt
abcd 1 0 0 2
abef 2 0 0 0
able 2 1 2 0
able 1 0 0 0
Скрипт перебирает все поля, (пропуская первое )и подсчитывает, сколько не -нулей на самом деле (, подсчет останавливается, как только находит не -ноль, но это всего лишь небольшая оптимизация ). Если были нули, отличные от -, печатается входная запись.
NF
— количество полей (столбцов )во входной записи (строки )и $i
ссылок на поле i
. Действие по умолчанию для c > 0
, в котором отсутствует блок {... }
, заключается в печати входной записи.
Эквивалентным способом написания этого скрипта был бы
awk '{ c = 0; for (i = 2; i <= NF && c == 0; ++i) { c += ($i != 0) } } c > 0 { print }'
В вашем коде обнаружены следующие проблемы:
while
выглядит как while (expression) { code }
, тогда как у вас while (expression) (expression)... { code }
. Это синтаксическая ошибка. BEGIN
выполняется до того, как первые данные будут считаны из файла, следовательно, $0
, $1
и т. д. не будут иметь значения внутри него.