awk:在if语句中处理变量

时间:2019-05-28 10:18:12

标签: bash awk logic

我试图了解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有一个简单的解释,但我个人看不到。

谢谢

2 个答案:

答案 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} }处理空文件。