2017-08-23 180 views
2

我已經看到關於此主題的幾個問題,但我缺乏將此轉換爲我的特定問題的能力。我有一個for循環通過子目錄循環,然後在每個目錄內的壓縮文本文件上執行.sh腳本。我想並行化這個過程,但我很努力應用gnu並行。gnu並行並行for循環

這裏是我的循環:

for d in ./*/ ; do (cd "$d" && script.sh); done 

我明白我需要輸入列表轉換成並行的,所以我一直在嘗試這樣的:

ls -d */ | parallel cd && script.sh 

雖然這似乎上手,我得到錯誤時的gzip試圖解壓目錄內的txt文件中的一個,說文件不存在:

gzip: *.txt.gz: No such file or directory 

但是,當我運行原始循環時,除了需要花費一個世紀才能完成之外,我沒有任何問題。另外,在使用parallel時,我只能得到gzip錯誤,考慮到我有超過1000個子目錄,這太奇怪了。

我的問題是:

  1. 我如何並行的情況下,我的工作?如何並行化將.sh腳本的應用程序並行化到其自己的子目錄中的1000個文件?即 - 我的問題的解決方案是什麼?我必須取得進展。

  2. 我錯過了什麼?語法,循環,壞腳本?我想學習。

  3. 並行實際上是否試圖並行運行所有這些.sh腳本?爲什麼我不知道每個.txt.gz文件都有錯誤?

  4. 是平行的應用程序的最佳選擇?有沒有更適合我需求的選擇?

回答

4

兩個問題:

  1. 在:

    ls -d */ | parallel cd && script.sh 
    

    什麼是平行只是cd,不script.shscript.sh只執行一次,畢竟parallel cd作業已經運行,如果沒有錯誤。這是一樣的:

    ls -d */ | parallel cd 
    if [ $? -eq 0 ]; then script.sh; fi 
    
  2. 你沒有目標目錄傳遞給cd。那麼,parallel執行什麼只是cd,它只是將當前目錄更改爲您的主目錄。最後的script.sh在當前目錄(從您調用該命令的位置)執行,其中可能沒有*.txt.gz文件,因此出現該錯誤。

您可以檢查自己的第一個問題與效果:

$ mkdir /tmp/foobar && cd /tmp/foobar && mkdir a b c 
$ ls -d */ | parallel cd && pwd 
/tmp/foobar 

pwd輸出打印一次,即使你有一個以上的輸入目錄。您可以通過引用命令修復它,然後用檢查第二個問題:

$ ls -d */ | parallel 'cd && pwd' 
/homes/myself 
/homes/myself 
/homes/myself 

您應該看到儘可能多的pwd輸出,有輸入目錄,但它始終是相同的輸出:你的home目錄。您可以通過使用替換爲當前輸入的{}替換字符串來修復第二個問題。檢查它:

$ ls -d */ | parallel 'cd {} && pwd' 
/tmp/foobar/a 
/tmp/foobar/b 
/tmp/foobar/c 

現在,你應該有所有輸入目錄正確列在輸出。

爲了您的具體問題,這應該工作:

ls -d */ | parallel 'cd {} && script.sh' 
+0

奈斯利解釋! –