Оценка переменной перед назначением в awk

#awk

#awk

Вопрос:

В следующем операторе awk:

 awk '$2 > maxrate {maxrate = $2; maxemp = $1} 
     END {print "highest hourly rate:", maxrate, "for", maxemp}' pay.data
  

выполняется для следующих данных:

 Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
  

Как это $2 > maxrate работает, поскольку оно оценивается до его присвоения $2 ?

Комментарии:

1. Все, что угодно, больше, чем ничего. Кроме отрицательных значений. И ноль.

Ответ №1:

Из руководства GNU awk

По умолчанию переменные инициализируются пустой строкой, которая равна нулю при преобразовании в число. Нет необходимости явно инициализировать переменную в awk, что вы бы сделали в C и в большинстве других традиционных языков.

Этот неявный способ, который обычно применяется для языков сценариев, очень удобен, но также оставляет место для ошибок или путаницы.


Например, в этом случае вы можете вычислить максимальное значение без необходимости инициализации max :

 awk '$2 > max{max = $2} END{print "max:", max}' file
max: 5.50
  

Но если вы сделаете то же самое для min , вы получите пустую строку в качестве результата, потому min что изначально она равна нулю как число и пуста как строка.

 awk '$2 < min{min = $2} END{print "min:", min}' file
min: 
  

Также max вычисление может завершиться ошибкой, если у нас все значения отрицательные. Поэтому было бы лучше назначить что-то в первый раз наверняка.

 awk 'NR==1{min=$2; next} $2<min{min = $2} END{print "min:", min}' file
min: 3.75
  

Этот способ должен работать как для, так min и max для чисел любого диапазона. В общем, при написании сценариев мы должны думать обо всех возможных случаях, когда наша не определенная и / или не инициализированная переменная будет инициализирована. И для случаев, когда она будет проверена перед получением значения.

Ответ №2:

По умолчанию, если вы не присваиваете какое-либо значение переменной, awk тогда ее значение по умолчанию будет равно null (без явного указания переменной, в которой мы могли бы напрямую присваивать ей значения awk ), поэтому ваше первое условие времени сравнивается с null, следовательно, оно становится истинным и переходит внутрь блока для дальнейшего выполнения операторов(где внутри блока он присваивается maxrate 2-му полю).

После самого первого выполнения, когда переменная maxrate получает в ней значение 2-го поля, затем в следующей строке она сравнивает значение 2-го поля 1-й строки со 2-м полем текущей строки и продолжает делать то же самое, пока не будут прочитаны все строки Input_file . Наконец, в END разделе кода он печатает его.