4

所以,我看到这个输出,我有点惊讶:

$ echo "a,b,c,d,e,f,g" | cut -d, -f-4
a,b,c,d
$ echo "a,b,c,d,e,f,g" | cut -d, -f6-
f,g
echo "a,b,c,d,e,f,g" | awk '{ print $0 | "cut -d, -f-4"; print $0 | "cut -d, -f6-"; }'
f,g
a,b,c,d

(作为旁注,我意识到这是在 中做的一件完全愚蠢的事情awk,但这是我看到它发生的唯一命令!)。

据我了解,这应该将记录按顺序传递到两个命令中。但由于某种原因,输出出现反转。如果我这样做

$ echo "a,b,c,d,e,f,g" | awk '{ print $0 | "echo hello"; print $0 | "echo goodbye"; }'
hello
goodbye

然后一切都按我预期的顺序进行。我认为这一定是某种竞争条件,但我很惊讶awk没有等待管道中的子命令完成。这是使用的已知问题awk还是特殊的问题gawk?有没有办法避免这样的陷阱?

编辑:

我也尝试过使用mawk...相同(反转)的结果,并且似乎两者都一致发生。

4

2 回答 2

5

为了确保完成一个外部命令,您必须关闭该命令。

$ echo "a,b,c,d,e,f,g" | awk 'BEGIN {cmd1 = "cut -d, -f-4"; cmd2 = "cut -d, -f6-"} { print $0 | cmd1; close(cmd1); print $0 | cmd2; close(cmd2)}'
a,b,c,d
f,g
于 2012-04-25T16:08:59.620 回答
4

我对此感到惊讶,但很明显 awk 并行运行命令。试试这个:

# time echo "a,b,c,d,e,f,g" | awk '{ print $0 | "sleep 2"; print $0 | "sleep 2"; }'

real    0m2.250s
user    0m0.030s
sys     0m0.060s
于 2012-04-25T16:09:52.117 回答