awk BEGIN 中的 $2 (字段引用)不起作用

awk BEGIN 中的 $2 (字段引用)不起作用

在下面的代码片段中,$2awk 返回空。我究竟做错了什么?我正在尝试找出 MAX 和 MIN 之间的差异。

#!/bin/ksh
if [ $# -ne 1 ]; then
        echo "Usage: sh `basename ${0}` filename";
        exit 1;
fi
if [ ! -s ${1} ]; then
        echo "file doesn't exist or is empty";
        exit 1;
fi
sed -e '/^$/d' -e '/^#/d' ${1} |
awk  -F'=' '
        BEGIN {
                MIN=$2; MAX=$2; print MIN;
        }
        {
                if ( $2 > MAX )
                {
                        MAX = $2;
                }
                else if ( $2 < MIN )
                {
                        MIN = $2;
                }
        }
        END {
                DIFF=MAX-MIN; print "DIFF:" DIFF;
        }
'

然而,这工作正常。为什么$2在该部分不起作用BEGIN

#!/bin/ksh
if [ $# -ne 1 ]; then
        echo "Usage: sh `basename ${0}` filename";
        exit 1;
fi
if [ ! -s ${1} ]; then
        echo "file doesn't exist or is empty";
        exit 1;
fi
sed -e '/^$/d' -e '/^#/d' ${1} |
awk -F'=' '
        {
                if ( MAX == "" || MIN == "" )
                {
                        MAX = MIN = $2;
                }
                else
                {
                        if ( $2 > MAX )
                        {
                                MAX = $2;
                        }
                        else if ( $2 < MIN )
                        {
                                MIN = $2;
                        }
                }
        }
        END {
                DIFF=MAX-MIN; print "DIFF:" DIFF;
        }
'

答案1

BEGIN模式被执行读取任何输入,因此不会在任何块中定义任何引用输入的变量,例如NR、字段等。你的第二种方法是正确的,而且更好。$0BEGINPOSIX awk 规范强调矿):

awk 实用程序应识别两种特殊模式:BEGIN 和 END。每个 BEGIN 模式应匹配一次并执行其关联的操作在读取输入的第一条记录之前...

1 顺便说一句,它也很好,因为它不会假设最小值或最大值受特定值(如 0)限制,这是人们在互联网上找到的许多单行假设的假设。

答案2

如果你想在输入文本的第一行执行命令,你应该使用NR==1pattern,而不是BEGIN.

awk  -F'=' '
    NR==1 {
            MIN=$2; MAX=$2; print MIN;
    }
    NR>1 {
            if ( $2 > MAX )
            {
                    MAX = $2;
            }
...

正如@jw013所述,BEGIN模式是在阅读第一行之前执行的操作。

相关内容