2012-04-25 30 views
4

所以,我看到這個輸出,我有點驚訝:(g)awk爲什麼會反轉這些輸出行?

$ 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不會等待在管子命令來完成。這是一個已知的問題,使用awkgawk?有什麼辦法可以避免這種陷阱?

編輯:

我嘗試了用mawk太...相同(逆轉)結果,並且似乎兩者一致的情況發生。

+2

這是該使用'date',我不得不在這兩個命令輸出怪異:-) – Benj 2012-04-25 15:49:12

+0

測試。 'echo「a,b,c,d,e,f,g」| awk'{print $ 0 | 「date \」+ A%s。%N \「」;打印$ 0 | 「date \」+ B%s。%N \「」; }'' – 2012-04-25 16:01:05

回答

4

爲了確保外部命令完成後,必須close命令。

$ 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 
+0

整潔,謝謝! – FatalError 2012-04-25 16:22:52

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