通过管道以交互方式使用 awk

Kir*_*ira 5 shell pipe awk

看着这个问题,我注意到awk如果文件被传送到标准输入,则无法读取用户输入,但如果从作为命令行参数给出的文件中读取输入,它的行为确实符合预期。

例如,如果您的awk脚本中有以下 BEGIN 块:

BEGIN {
    printf "Enter input: "
    getline var < "-"
}
Run Code Online (Sandbox Code Playgroud)

如果你像 一样运行它awk -f ./script.awk file.txt,它会提示用户输入,然后继续处理file.txt。但是,如果您像 一样运行cat file.txt | awk -f ./script.awk,我想 awk 会将它从管道中获取的内容解释为用户的输入(因此getline将填充var的第一行file.txt)。

有没有办法让awk行为就像从文件中读取一样,但在管道中使用?

我可以使用临时文件,当然,但这远不优雅。

jll*_*gre 5

进程替换适用于简单的情况,但这里有一种通用方式,允许在处理管道数据的同时与控制台用户对话:

BEGIN {
    printf "Enter input: " > "/dev/tty"
    getline var < "/dev/tty"
    print var
}
Run Code Online (Sandbox Code Playgroud)


dha*_*hag 3

除了临时文件之外,您还可以使用 shell 对进程替换的支持(这假设bashzsh或某些实现ksh(该功能由 ksh88 引入)):

awk -f ./script.awk <(cat file.txt)
Run Code Online (Sandbox Code Playgroud)

这将提供awk一个文件名来代替构造<(...),该构造在读取时将包含所附命令的输出。