2011-10-01 20 views
30

我有一些骯髒的工作要做,所以Bash腳本似乎是一個不錯的選擇。我是Bash新手,經歷讓我感到沮喪。Bash:逐行讀取文件並將每個段作爲參數傳給其他prog

文件mapfiles.txt由以下幾行組成。每行有四個由空格分隔的段。每個片段表示外部程序名稱「prog」的輸入參數。例如, 「cm19_1.png」 是文件名, 「0001」 的指數, 「121422481」 的經度,而 「31035995」 的緯度

文件:mapfiles.txt

cm19_1.png 0001 121422481 31035995 
cm19_2.png 0002 121423224 31035995 
cm19_3.png 0003 121423967 31035995 
… 

我想要執行類似的命令到每一行。如下所示,prog的輸入參數順序稍有不同。因此編寫一個bash腳本來處理重複的工作是有意義的。

[Usage] prog <index> <longitude> <latitude> <filename> 
example: prog 0001 121422481 31035995 cm19_1.png 

通常,bash腳本會以這種方式操作:從mapfiles.txt

  • 拆分

    1. 讀取一行段
    2. 呼叫用正確的參數順序PROG

    這裏是run.sh.

    #!/bin/sh 
    
    input=mapfiles.txt 
    cmd=prog 
    
    while read line 
    do 
         file=$(echo $line | cut -d' ' -f1) 
         key=$(echo $line | cut -d' ' -f2) 
         log=$(echo $line | cut -d' ' -f3) 
         lat=$(echo $line | cut -d' ' -f4) 
         echo $cmd $key $log $lat $file 
    done < "$input" 
    

    我的預期是什麼

    prog 0001 121422481 31035995 cm19_1.png 
    prog 0002 121423224 31035995 cm19_2.png 
    prog 0003 121423967 31035995 cm19_3.png 
    … 
    

    實際結果我得到的是困惑我

    cm19_1.png21422481 31035995 
    cm19_2.png21423224 31035995 
    cm19_3.png21423967 31035995 
    

    問題

    1. 哪裏是 '前衛'?
    2. 白色空間在哪裏?
    3. 參數順序有什麼問題?

    嗯......我在我的Mac上用vim編寫了這個腳本,並將它複製到Scientific Linux盒子和一個gentoo盒子中。這三個人得到同樣荒謬的結果。

  • +1

    不可再生這裏。尋找錯別字。此外,而不是所有的削減只使用'讀取文件密鑰日誌lat'。 * UPD *查看答案。 –

    +0

    當與循環中的ssh結合使用時,請看一下這個問題:http://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash – Christian

    回答

    42

    可以簡化這個有很多:

    while read file key log lat 
    do 
        echo "$cmd" "$key" "$log" "$lat" "$file" 
    done < "$input" 
    
    +0

    這是一個不錯而優雅的技巧。 –

    +6

    您可以進一步簡化它。你不需要爲每個參數使用單獨的變量:'while read line;做echo $ cmd $ line;完成<「$ input」' – Idelic

    2

    prog可能已經消失了,因爲$cmd不出口。您的/ bin/sh版本可能會在單獨的shell中執行while語句。這不應該是這樣,我的bash安裝不是這種情況,但是也許你在這個部門的行爲有趣。

    UPD我看到你有幾個盒子可以得到相同的結果。這使得子殼理論不太可能。也許你的腳本和/或源文件中有一些有趣的字符。

    我已將您的腳本和您的源文件複製並粘貼到我的gentoo框中,並提供了預期的結果。也許你應該這樣做,並將文件與原始文件進行比較。

    +2

    非常感謝。你的評論幫助我找出真正出問題的地方。這不是Bash腳本 - 我在三個不同的盒子上測試它 - 這是出錯的mapfiles.txt。該文件在Windows中生成,每行以^ M結尾。刪除^ M後,一切順利。 –

    8

    使用GNU並行,你可以做一個單行+你得到它的並行完成免費:

    cat mapfile.txt | parallel --colsep '\s' prog {2} {3} {4} {1} 
    

    觀看介紹視頻,以瞭解更多:http://www.youtube.com/watch?v=OpaiGYxkSuQ

    相關問題