Я фильтрую некоторые данные с помощью awk
(версия 20070501, в MacOS), но у меня возникла проблема с синтаксисом при применении нескольких условий отрицательного соответствия к значениям в определенном столбце.
Вот общий пример, которыйЯ думаю, что захватывает мою проблему.
Ввод:
foo,bar
bar,foo
foo,bar
bar,foo
С этим кодом я удаляю совпадения для foo
в столбце 2:
awk 'BEGIN { FS=OFS="," } ; { if ($2 !~ /foo/ ) print $0}'
Я получаю вывод, который я ожидал:
foo,bar
foo,bar
Затем я добавляю дополнительное условие к оператору if
, чтобы также удалить все значения, соответствующие bar
в столбце 2:
awk 'BEGIN { FS=OFS="," } ; { if ($2 !~ /foo/ || $2 !~ /bar/) print $0}'
Я получаю вывод, которого я не ожидал:
foo,bar
bar,foo
foo,bar
bar,foo
Я не ожидал, что строки будут возвращены, что и было моей целью.Так что же происходит?
Два условия отменяют друг друга?Я прочитал документацию GNU awk для логических выражений , в которой говорится:
'&&' и '||'Операторы называются операторами короткого замыкания из-за того, как они работают.Оценка полного выражения является «короткозамкнутой», если результат можно определить на полпути посредством его оценки.
Из этого фрагмента я не был уверен, как добиться прогресса.Или проблема в том, что синтаксис неправильный?Или и то и другое?
Обновление:
После комментариев и помощи от @ wiktor-stribiżew вот лучшее представление о проблеме:
1 2 3 4 5
foo bar foo bar FY 2008 Program Totals
foo bar foo bar FY 2009 Program Totals
foo bar foo bar Fiscal Year 2010 Program Totals
foo bar foo bar Fiscal Year 2011 Program Totals
foo bar foo bar Fiscal Year 2012 Program Totals
foo bar foo bar Fiscal Year 2013 Program Totals
foo bar foo bar Fiscal Year 2014 Program Totals
foo bar foo bar Fiscal Year 2015 Program Totals
foo bar foo bar Fiscal Year 2016 Program Totals
foo bar foo bar Fiscal Year 2017 Program Totals
Myошибочный код будет:
awk 'BEGIN { FS=OFS="\t" } ; { if ($5 !~ /Fiscal.*Program Totals/ || $5 !~ /FY.*Program Totals/) print $0}'
Принятый ответ ниже разрешает это.