system("foo") 只是调用程序foo 并返回foos 退出状态(即,0 表示成功,非零表示失败)。您想要捕获foo 的输出(即foo 写入标准输出的文本),而不是退出状态,因此调用system() 是错误的方法。您在问题中看到的是 xclip -o 的输出与您的 awk 脚本的输出混合在一起。
这就是你想做的事情(使用date 而不是xclip,因为这是每个人都可以使用的命令):
$ awk '
NR==4 {
cmd = "date +%F"
$0 = $0 " " ( (cmd | getline line) > 0 ? line : "N/A" )
close(cmd)
}
{ print }
' file
orange
apple
pair
mango 2021-09-06
grape
请参阅https://www.gnu.org/software/gawk/manual/gawk.html#Getline_002fVariable_002fPipe 了解有关上述内容的更多信息,并确保阅读http://awk.freeshell.org/AllAboutGetline 以了解我为什么在使用getline 的输出之前测试它的退出状态,以及为什么它在许多情况下都不能使用(但这个是合适的)。
作为“单行”,上述内容将是:
awk 'NR==4 { cmd = "date +%F"; $0 = $0 " " ( (cmd | getline line) > 0 ? line : "N/A" ); close(cmd) } { print }' file
如果它有用,这里有一个函数,它可以与 awk 等效,作为 shell 的命令替换:
$ cat cmdsub.awk
function cmdsub(cmd, line, n, out, cmd_stat, gl_stat) {
ERRNO = ""
while ( ( gl_stat=(cmd | getline line) ) > 0 ) {
out = (n++ ? out ORS : "") line
}
cmd_stat = close(cmd)
# If the above pipeline loop succeeded then all 3 error/status
# variables will be 0 but if the above pipeline loop failed then
#
# a) if cmd failed then
# i) ERRNO will be null
# ii) gl_stat will be 0 if 1st iteration, 1 otherwise.
# iii) cmd_stat will be non-zero if GNU awk,
# poorly defined for POSIX awk so YMMV.
#
# b) if cmd succeeded and getline failed then
# i) ERRNO will be non-null if GNU awk, null otherwise.
# ii) gl_stat will be less than zero
# iii) cmd_stat will be 0
if ( (ERRNO == "") && ( (gl_stat != 0) || (cmd_stat != 0) ) ) {
ERRNO = sprintf("CMD_STAT: %d, GL_STAT: %d", cmd_stat, gl_stat)
}
return out
}
BEGIN {
print "foo", cmdsub("date +%F"), "bar"
print (ERRNO ? "Failure: " ERRNO : "Success")
exit (ERRNO ? 1 : 0)
}
$ awk -f cmdsub.awk
foo 2021-09-06 bar
Success
$ echo $?
0
它使用一个名为 ERRNO 的全局变量,与 gawk 用于 getline 失败的相同(注意:尽管它的名字,ERRNO 是一个字符串,而不是一个数字),并依赖于 close(cmd) 返回一个失败cmd 失败时的退出状态,这在 gawk 中发生,但在其他 awks YMMV 中发生,因为 POSIX 标准在这一点上含糊不清。
有关ERRNO 和close() 的更多信息,请参阅: