我试图了解awk
如何处理if
语句中的变量。
这是一个玩具文本文件:
$ cat myscript.sh
#! /bin/bash
set -eu
set -o pipefail
IFS=$'\n\t'
for arg in $@; do
echo "do something with file $arg"
done
现在我要awk
打印文件中最长的行。
我想这样做:
$ awk '{max = 0}{if (length($0) > max) {max = length($0)} else {}} END {print max}' myscript.sh
但是这会打印最后一行的长度。 但是,当我运行以下命令时:
awk '{if (length($0) > max) {max = length($0)} else {}}END{print max}' myscript.sh
结果正确,并且打印正确的长度35
。
我真的无法理解为什么在max
语句之前指定if
变量时无法识别条件。
我相信awk-gurus
有一个简单的解释,但我个人看不到。
谢谢
答案 0 :(得分:0)
您可以稍微更改第一个命令以使其起作用:
awk 'BEGIN{max = 0}{if (length($0) > max) {max = length($0)} else {}} END {print max}' myscript.sh
这样,您可以在脚本开头初始化变量max。如果没有BEGIN语句,则每一行的max将更新为0。
但是,awk变量具有取决于上下文的默认值。您可以阅读this来了解其背后的逻辑。
awk中的变量可以分配数字值或字符串值。变量所拥有的值的类型可以在程序的整个生命周期内发生变化。默认情况下,变量会初始化为空字符串,如果转换为数字,则为零。
使用此命令:
awk '{if (length($0) > max) {max = length($0)} else {}}END{print max}' myscript.sh
Awk将在第一行将max初始化为0,因为您正在将其与length($ 0)(它是一个整数)进行比较。
答案 1 :(得分:0)
@Corentin已经解释了您的问题,因此您应该将他/她的答案保留为可接受,但是仅供参考,打印文件中最长行的长度的正确方法是:
awk '{cur=length()} cur>max{max=cur} END{print max+0}' myscript.sh
这确保即使所有行都为空,max也将为数字,每行不多次调用length(),并确保即使输入为空也将获得数字输出(就像{{1} }处理空文件。