Awk

具有反轉效果的 awk 系統呼叫

  • January 15, 2022

我有一個數據文件,其中包含在特定關鍵字(DATAEND)之間的多個數據塊。我正在使用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,blockname2blockname1_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 的退出狀態testwhile循環條件之間的不同定義awk

一個積極test的命令導致退出程式碼0為 TRUE 和一個負的退出程式碼1為 FALSE。

但是,在awk循環while中解釋0為 FALSE 和1TRUE,因此定義正好相反。

舉個例子:

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 ) 

顯示預期的行為。

引用自:https://unix.stackexchange.com/questions/323767