awk состояние истинного и ложного

9

Я сталкивался с тем, что, если мы используем awk 0 inputfile, он не будет печатать что-либо, потому что 0означает ложные условия.

Если мы используем awk 1 inputfile, он напечатает все как 1среднее значение true для каждой строки, которую интерпретирует awk.

Если мы используем awk any_string inputfile, он ничего не печатает, потому что все переменные awk инициализируются как ноль, таким образом, false.

Но если мы используем awk any_integer inputfileего, оно станет правдой и напечатает каждую строку файла, могу ли я знать, в чем причина?

Я не могу найти это было объяснено в GNU awkвручную , хотя.

sylye
источник
3
по any_integerЯ полагаю , вы имеете в виду буквальное число , как и 7, 89т.д .. если да, то причина любое число , отличное 0средство trueусловие
Sundeep

Ответы:

13

Истина для awk - это либо непустая строка, либо ненулевое число (с числами, являющимися десятичным целым числом или с плавающей запятой, а также с некоторыми реализациями awk, также поддерживаются шестнадцатеричные или восьмеричные). Вещи, заключенные в двойные кавычки, являются строками, буквенные числа без кавычек - это числа, но для всего остального существуют сложные правила, позволяющие определить, следует ли что-то рассматривать как строку или число. В awkруководстве GNU есть целая глава об этом .

Правда:

  • awk '1' (ненулевое число)
  • awk '1e8' (ненулевое число)
  • awk '-0.01' (ненулевое число)
  • awk '"foo"' (непустая строка)
  • awk '"0"' (непустая строка)
  • awk '0 ""' (конкатенация дает строку, которая здесь не пуста)
  • echo 0 | awk '$1 ""' (то же самое для поля $ n)
  • awk 'substr("000", 1, 1)'(результатом substr()всегда является строка)
  • echo '0foo' | awk '$0' ($ 0 - нечисловая строка, поэтому рассматривается как строка (не пустая))

Ложь:

  • awk '0' (0 число)
  • awk '""' (пустой строкой)
  • echo 0000e123 | awk '$1' ($ 1 считается числом, если это числовая строка, которая здесь и равна 0)
  • echo ' 0 ' | awk '$0' (начальные и конечные пробелы игнорируются, чтобы определить, является ли строка числовой).
  • awk '" 2foo" - 2' (строка, содержащаяся в арифметическом выражении, преобразуется в число, при этом все, что находится за номером, игнорируется)
  • awk 'unset_or_empty_variable' (пустой строкой)
  • awk '"non-numerical-string" + 0'

YMMV:

  • awk '1e-500' (некоторые будут жаловаться, некоторые будут воспринимать это как 0)
  • awk '"0x1" + 0'(не все реализации awk поддерживают шестнадцатеричные числа, в тех, которые делают "0x1", преобразуются 1в другие, в 0некоторые. Некоторые версии спецификации POSIX непреднамеренно требовали реализации для поддержки этого шестнадцатеричного числа, и оно было отозвано позже. Тем gawkне менее распознает это шестнадцатеричное число, когда оно POSIXLY_CORRECTнаходится в окружение)
  • awk '010 - 8' (то же самое (ну, не совсем так, как 010 здесь буквально, а не преобразовано из строки) для восьмеричных)
  • awk '0x1 - 1'awkреализациях, которые не поддерживают шестнадцатеричные числа, 0x1это конкатенация 0и x1переменная, которая выдает, "0"которая преобразуется в число (0), если вычесть, 1вы получите -1ненулевое число).

Это означает, что если вы хотите проверить, не является ли строка непустой, вам не следует делать:

awk '$ 1 {print $ 1, "not empty"}'

Но

awk '$1 != "" {print $1, "is not empty"}'

В противном случае он не сказал бы 0или -0000E+00001234не является пустым.

Стефан Шазелас
источник
Впечатляющий и подробный ответ! Хотя один вопрос: в последнем примере, который вы дали, я попробовал синтаксис, и первый работает, где он пропускает пустые $ 1 и печатает только те строки с $ 1 непустыми, потому что если $ 1 - пустая строка, это будет Неверно, и, следовательно, не печатает вывод, не так ли?
sylye