2014-02-24 33 views
2

我想要製作一個bash腳本,它會經過指定的目錄,找到文件,對它們的內容進行排序,然後創建一個新文件。我現在遇到的唯一問題是如何爲每個文件指定一個不同的名稱。代碼:通過shell腳本唯一命名文件

find $1 -name '*.grd' -exec sort -k 2,2 {}> {}.std \; 

回答

3

當你做你的重定向find命令裏面,外殼執行重定向只有一次,開始find之前。由於-exec直接使用execv()調用來調用子級 - 沒有外殼 - 其參數內的重定向不會被遵守。 (重定向如>file由調用shell執行,而不是作爲執行過程的一部分由操作系統執行)。

在大多數情況下的控制,不要試圖用find -exec,而是直接處理在外殼的結果:

while IFS= read -r -d '' filename; do 
    sort -k2,2 <"$filename" >"${filename}.std" 
done < <(find "$1" -name '*.grd' -print0) 

另外,如果你堅持使用find -exec,它已經推出了殼本身,然後執行處理和重定向有:

find "$1" -name '*.grd' -exec bash -c \ 
    'while (($#)); do sort -k2,2 <"$1" >"$1.std"; shift; done' _ {} + 

的其它方法可在the UsingFind page on the Wooledge wiki(特別是第5至8看到)。

+0

起初我有點困惑,因爲我對腳本很陌生。代碼似乎工作,但我需要能夠正確解釋它。你能澄清IFS嗎? – user3344763

+1

@ user3344763清除IFS可以防止'read'剝離尾部空格,這是默認情況下執行的 - 如果文件名以空格或製表符結尾,則會導致錯誤。類似地,要讀取的'-d'''參數告訴它期望NUL分隔的內容,如果文件名包含換行符(這在UNIX中是合法的),這會使代碼安全。發現'-print0'參數反過來會告訴它在發送文件名時使用NUL分隔符。 –

+0

@ user3344763 ...一般來說,在說它「有效」之前,用空格測試任何shell腳本與空白 - 特別是尾隨空格 - 換行符等是一個好主意。如果不小心的話,有很多容易陷入的錯誤和錯誤。 –