給定一個包含幾百萬個文件的目錄,我們希望從這些文件中提取一些數據。命令輸出重定向
find /dir/ -type f | awk -F"|" '$2 ~ /string/{ print $3"|"$7 }' > the_good_stuff.txt
這不會放大,所以我們介紹xargs的。
find /dir/ -type f -print0 | xargs -0 -n1 -P6 awk -F"|" '$2 ~ /string/{ print $3"|"$7 }'
這將產生有效的輸出,無論我們多長時間運行。 Sweet可以通過在該命令上附加> the_good_stuff_from_xargs.txt
來將它寫入文件。除了現在文件包含損壞的行。
讓我感到震驚的是,在查看xargs在我的終端中作爲STDOUT打開的六個子進程的輸出時,數據看起來很好。數據重定向到文件系統的時刻是出現損壞的時刻。
我試圖追加以下命令。
> myfile.txt
>> myfile.txt
| mawk '{print $0}' > myfile.txt
並重定向或以其他方式的其他各種概念它與數據中的每個版本被損壞寫入磁盤之前「池」的xargs的的輸出。
我很積極的原始文件沒有格式錯誤。我確信,當在終端中查看標準輸出時,xargs的命令產生有效輸出,長達10分鐘盯着它吐出文本...
本地磁盤是SSD ......我正在讀寫來自同一個文件系統。
爲什麼重定向find /dir/ -type f -print0 | xargs -0 -n1 -P6 awk -F"|" '$2 ~ /string/{ print $3"|"$7 }'
的輸出會導致數據變得格式錯誤?
編輯
我目前還不能安裝無緩衝,但stdbuf -oL -eL
修改命令的輸出進行行緩衝,因此,從理論上說,應該做同樣的事情。
我試過stdbuf xargs cmd
和xargs stdbuf cmd
這兩個都導致了非常虛線。
-P6
是必需的,才能在任何合理的時間內完成此命令。
EDIT 2
爲了澄清... xargs
和它的-P6
標誌是要解決的問題,因爲我們的工作目錄中的有一萬必須掃描文件的要求。
顯然,我們可以刪除-P6
或以其他方式停止運行一次多個就業機會,而且這不是真正回答的爲什麼輸出越來越錯位也不是一個現實的方法輸出如何是問題恢復到「正確」的狀態,同時仍然完成規模的任務。
解決方案
接受的答案使用parallel
其工作過的最好的了所有的答案提及。
我跑的最後一個命令看起來像。 time find -L /dir/ -type f -mtime -30 -print0 | parallel -0 -X awk -f manual.awk > the_good_stuff.txt
awk很困難,所以我將-F"|"
轉移到命令本身。默認情況下,並行會爲每個核心啓動一個作業,如果需要,可以使用-j
來設置較低的作業數量。
用真正的科學術語來說,這是一個巨大的速度增加。經過6分鐘6分鐘後,未經測量的小時數(可能爲6+)是10%,因此可能在一小時內完成。
一個問題是,您必須確保在parallel
中運行的命令不會嘗試寫入文件...,以便有效地繞過並行執行的作業的輸出處理!
最後沒有-X
平行行爲類似於xargs -n1
。
標準輸出在寫入終端時被行緩衝,但在寫入管道或文件時被完全緩衝。 – Barmar
使用'Expect'附帶的'unbuffer'命令。 – Barmar
刪除'-P6';這會導致6個異步進程隨機寫入輸出,並且在緩衝區填充時寫入部分行,並且不同的進程在不同的位置寫入不同的局部行等。如果您必須使用-P6,則需要具有這6個進程寫入不同的文件,以便它們不會對彼此的輸出進行踐踏。這反過來可能意味着運行一個運行'awk'的shell腳本,並將I/O重定向到一個單獨的文件(使用'mktemp',可能是基於腳本PID的名稱)。 –