Awk
具有反轉效果的 awk 系統呼叫
我有一個數據文件,其中包含在特定關鍵字(
DATA
,END
)之間的多個數據塊。我正在使用awk
基於從所述塊中獲取的文件名將數據塊提取到單獨的文件中。blockname
由於某些數據塊共享相同的名稱,如果文件(“ ”)已經存在,我將使用遞增的整數重命名每個輸出文件:#cat input.file useless stuff1 DATA blockname1 data1 data1 END useless stuff2 DATA blockname2 data2 data2 END useless stuff3 DATA blockname1 data3 data3 END useless stuff4
預期將是三個輸出文件
blockname1
,blockname2
和blockname1_1
(注意最後一個文件是如何分配一個整數的)#cat blockname1 DATA blockname1 data1 data1 END
(其他相應的……)
現在以下腳本可以按我的意願工作:
awk '/DATA/,/END/ { if ( $1 ~ /DATA/ ) { block=$2 ; i=0 ; file=block while ( system("test ! -e " file ) ) { i++ ; file=block"_"i ; print file } } print $0 > file }' input.file
我的問題在於
while
循環及其係統呼叫:我希望
system("test -e " file)
在file
存在時為 TRUE,如果file
尚不存在則為 FALSE,即while
循環僅在存在時開始執行,如果(新的)尚不存在file
則中斷。file
但是,如果我使用
system("test -e " file)
(並使用 使其冗長print file
),我有一個同名的無限循環,整數後綴增加,反之system("test !-e " file)
則給出所需的結果。所以這與我的預期完全相反。
好的,我想:問題在於 TRUE 和 FALSE 的退出狀態
test
和while
循環條件之間的不同定義awk
。一個積極
test
的命令導致退出程式碼0
為 TRUE 和一個負的退出程式碼1
為 FALSE。但是,在
awk
循環while
中解釋0
為 FALSE 和1
TRUE,因此定義正好相反。舉個例子:
awk '{ while ( 0 ) ; { print "0" } }' file
不會產生任何輸出,而
awk '{ while (1) ; { print "1" } }' file
將列印無窮大
1
的 s。因此,最佳實踐是在這種組合中明確
while ( system("command") == 0 )
或者
while ( system("command") == 1 )
分別。
所以在我的情況下
while ( system("test -e " file ) == 0 )
顯示預期的行為。