2013-03-12 50 views
1

我有一個運行兩個命令的腳本。第一條命令是將數據寫入臨時文件。第二個命令是在第一個命令在後臺運行時管道到awk。 awk在第二個命令中需要從臨時文件中讀取數據,但它比數據寫入臨時文件更快地解析自己的數據。awk使用getline從文件讀取數據,因爲它正在寫入

下面是一個例子:

#!/bin/bash 

command1 > /tmp/data.txt & 
# command1 takes several minutes to run, so start command 2 while it runs in the background 
command2 | awk ' 
    /SEARCH/ { 
     #Matched input so pull next line from temp file 
     getline temp_line < "/tmp/data.txt" 
    } 
' 

這工作,除非AWK從command2的解析數據如此之快,是command1無法跟上它。即awk在command1完成寫入之前從/tmp/data.txt獲取EOF。

我也試着包裝一些檢查周圍的函數getline,如:

while ((getline temp_line < "/tmp/data.txt") < 0) { 
    system("sleep 1") # let command1 write more to the temp file 
} 
# Keep processing now that we have read the next line 

但我認爲,一旦它擊中EOF在臨時文件,停止嘗試從中讀取數據。或類似的東西。

只要command1寫入臨時文件的速度比awk試圖讀取的速度快,整個腳本就會工作。如果我在這兩個命令之間放置了sleep 10命令,那麼臨時文件將生成足夠的緩衝區,並且腳本會生成我需要的輸出。但是我可能會解析比我測試的文件大得多的文件,或者命令可能以不同的速度在不同的系統上運行等等,所以我希望有一個安全機制等待文件,直到數據寫入它爲止。

任何想法,我可以做到這一點?

回答

1

我認爲你需要在迭代之間關閉這個文件,並且從頭再讀回到你之前讀過的地方,像這樣(未經測試);

sleepTime = 0 
while ((getline temp_line < "/tmp/data.txt") <= 0) { 
    close("/tmp/data.txt") 
    system("sleep " ++sleepTime) # let command1 write more to the temp file 
    numLines = 0 
    while (++numLines < prevLines) { 
     if ((getline temp_line < "/tmp/data.txt") <= 0) { 
      print "Aaargghhh, my file is gone!" | "cat>&2" 
      exit 
     } 
    } 
} 
++prevLines 

注意,我建立一個變量「睡眠時間」有你的命令睡眠再通過每一次循環中,所以如果它把你的tmp文件很長的時間來填補你的第二個命令等待更長的時間它每次迭代。只要你喜歡就用或不用。使用getline和system()命令的嵌套循環似乎都很笨拙,但容易出錯 - 我不禁想到可能有更好的方法,但我不知道什麼離開了我的頭頂。

+0

Thanks Ed。這個劇本真的很接近現在的工作...... – 2013-03-14 16:00:02

+0

@RustyLemur如果你分享什麼還沒有工作,也許我們可以提供幫助。 – 2013-03-14 16:52:02

相關問題