AWK:使用 'system(external programm)' 替换将文本附加到特定行
AWK: append text to specific line with 'system(external programm)' substitution
我有一个名为 data
的文件,如下所示:
orange
apple
pair
mango
grape
通过使用
awk -i inplace '{if (NR==4) [=17=]=[=17=]" is sweet"}{print}' data
,我得到:
orange
apple
pair
mango is sweet
grape
我正在尝试通过 system()
获得相同的结果,但我不知道如何实现。
echo is sweet | xclip
xclip -o
输出 is sweet
。我在努力
awk -i inplace '{if (NR==4) [=14=]=[=14=](system("xclip -o"))}{print}' data
和cat -n data
给我
1 orange
2 apple
3 pair
4 is sweet
5 mango0
6 grape
芒果和葡萄被推到下一行,is sweet
在第 4 行是独立的,mango
最后有一个 0
。
我如何更改命令,并且仍然使用 system("xclip -o")
以便第 4 行显示 mango is sweet
,没有任何附加的 0
也没有额外的行,即与第一个示例一样?
我是 awk 的新手,如有任何帮助,我们将不胜感激。
system("foo")
只是调用一个程序 foo
和 returns foo
s 退出状态(即 0 表示成功,非- 失败为零)。您想要的东西可以捕获 foo
的 output(即 foo
写入标准输出的文本),而不是 exit status,所以调用system()
是错误的做法。您在问题中看到的是 xclip -o
的输出与 awk 脚本的输出混合在一起。
这是做你想做的事情的方法(使用 date
而不是 xclip
因为这是每个人都可用的命令):
$ awk '
NR==4 {
cmd = "date +%F"
[=10=] = [=10=] " " ( (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 for more information on the above and make sure to read http://awk.freeshell.org/AllAboutGetline 了解为什么我要在使用它的输出之前测试 getline
的退出状态,以及为什么它不是在许多情况下使用的东西(但这个是合适的)。
作为“单线”,上面的内容是:
awk 'NR==4 { cmd = "date +%F"; [=11=] = [=11=] " " ( (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()
的更多信息,请参阅:
我有一个名为 data
的文件,如下所示:
orange
apple
pair
mango
grape
通过使用
awk -i inplace '{if (NR==4) [=17=]=[=17=]" is sweet"}{print}' data
,我得到:
orange
apple
pair
mango is sweet
grape
我正在尝试通过 system()
获得相同的结果,但我不知道如何实现。
echo is sweet | xclip
xclip -o
输出 is sweet
。我在努力
awk -i inplace '{if (NR==4) [=14=]=[=14=](system("xclip -o"))}{print}' data
和cat -n data
给我
1 orange
2 apple
3 pair
4 is sweet
5 mango0
6 grape
芒果和葡萄被推到下一行,is sweet
在第 4 行是独立的,mango
最后有一个 0
。
我如何更改命令,并且仍然使用 system("xclip -o")
以便第 4 行显示 mango is sweet
,没有任何附加的 0
也没有额外的行,即与第一个示例一样?
我是 awk 的新手,如有任何帮助,我们将不胜感激。
system("foo")
只是调用一个程序 foo
和 returns foo
s 退出状态(即 0 表示成功,非- 失败为零)。您想要的东西可以捕获 foo
的 output(即 foo
写入标准输出的文本),而不是 exit status,所以调用system()
是错误的做法。您在问题中看到的是 xclip -o
的输出与 awk 脚本的输出混合在一起。
这是做你想做的事情的方法(使用 date
而不是 xclip
因为这是每个人都可用的命令):
$ awk '
NR==4 {
cmd = "date +%F"
[=10=] = [=10=] " " ( (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 for more information on the above and make sure to read http://awk.freeshell.org/AllAboutGetline 了解为什么我要在使用它的输出之前测试 getline
的退出状态,以及为什么它不是在许多情况下使用的东西(但这个是合适的)。
作为“单线”,上面的内容是:
awk 'NR==4 { cmd = "date +%F"; [=11=] = [=11=] " " ( (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()
的更多信息,请参阅: