为什么我的AWK脚本等我按下按键?

时间:2019-07-09 09:39:28

标签: awk

我今天开始学习AWK,并编写了一个脚本来计算2的幂。但是,当我启动它时,它会等待我按enter键,并且在完成打印两次的幂时,尽管在End节中定义了它,但它不会打印单词“ End”。

这是我的代码:

Exception

3 个答案:

答案 0 :(得分:2)

您通过在BEGIN和END({while ... }})之间提供代码来处理该输入,来告诉脚本期望输入。直到您通过按Enter键提供输入后,该部分才开始,然后直到您通过键入control-D结束输入,然后您的END部分将被执行,该部分才结束。

听起来这是您打算写的内容:

BEGIN{
    print "Power of two"
    x=0

    while(res<=1000){
        res = 2^x
        print 2 "^" x "=" res
        x++
    }

    print "End"
}

或者如果您出于某些原因真的想拥有END部分:

BEGIN{
    print "Power of two"
    x=0

    while(res<=1000){
        res = 2^x
        print 2 "^" x "=" res
        x++
    }

    exit
}
END{
    print "End"
}

答案 1 :(得分:2)

您的程序在按键时执行进一步操作的原因是它正在等待输入。使用管道时,输入通常来自文件,或者来自其他命令的输出。但是,awk有时会等待来自/dev/stdin的输入。当您在不使用任何文件作为参数的情况下调用程序时,就是这种情况(请参见[1]部分扩展的说明:总体程序结构),或使用作为参数(请参见{{3 }}部分操作数)。

$ awk -f source.awk                 # input from /dev/stdin via keyboard 
$ awk -f source.awk [file] -        # input from /dev/stdin via [file and] keyboard
$ cmd | awk -f source.awk           # input from /dev/stdin via pipe
$ cmd | awk -f source.awk [file] -  # input from /dev/stdin via [file and] pipe

请注意,上述情况可能需要/dev/stdin的输入。输入的需要取决于awk的程序结构。因此,我们现在可以问自己以下问题:

  

awk何时需要文件,命令,键盘或任何其他可能的输入形式的输入?

awk程序由以下形式的对组成:

pattern { action }

其中pattern通常是确定是否应执行action的逻辑条件。 Posix awk可以识别两种特殊模式BEGINEND。 Gnu awk还有其他特殊模式,例如BEGINFILEENDFILE,但是对于这个答案,我们可以将它们分类为常规模式。现在,我们可以进行以下声明(请参见[1]小节特殊模式):

  • 常规模式总是需要输入。
  • 特殊模式BEGIN 不需要(除非包含getline的情况)
  • 特殊模式END 始终要求在执行输入之前先读取输入内容

由此我们可以说:

  

awk程序如果

不需要输入      
      
  • 它仅由BEGIN个模式组成,这些模式不调用getline
  •   
  • BEGIN模式在调用任何exit之前调用getline例程
  •   
     

在任何其他情况下,awk都需要输入!

最后一条语句来自绑定到exit语句的规则。 exit语句应按它们在程序源中发生的顺序调用所有END动作,然后在不读取进一步输入的情况下终止程序 。 (请参见[1]小节操作

基于上述内容,我们现在可以回答OP的问题:

  

为什么我的AWK脚本等待我按下按键?

由于OP的程序大致如下:

 BEGIN { something without exit }
 pattern { something else }
 END { something final }

这将需要输入。此外,OP将其称为

$ awk -f file.awk

表示输入来自/dev/stdin,在这种情况下,输入来自键盘。因此,awk将等待执行常规操作模式对,直到从键盘接收到一条记录(此处为一行)。即按一些键,然后按 Enter 。每次发送这样的行时,awk都会处理所有常规模式。 END模式将仅在输入完成时执行。您可以通过键盘发送文件结尾(EOF)来通知awk通过键盘的输入已完成。通过按 Ctrl - D 来完成。

可以在[1]的答案中找到对代码的干净重写。回答Ed Morton的快速解决方法。

Jotne

答案 2 :(得分:1)

awk的中间部分需要一些输入(如@Sundeep所写)

尝试

echo "50" | awk '
BEGIN{
    print "Power of two"
    x=0
}
{
while(res<=$1){
    res = 2^x
    print 2 "^" x "=" res
    x++
}
}
END{
    print "End"
}'
Power of two
2^0=1
2^1=2
2^2=4
2^3=8
2^4=16
2^5=32
2^6=64
End