2009-10-14 48 views
2

想我已經得到了文件處理特殊字符在bash for ... in循環

file1 
"file 1" 
file2 

一個for ... in循環打破它之間的空白,而不是新行的列表:

for x in $(ls); do 
    echo $x 
done 

結果:

file 
1 
file1 
file2 

我想對每個文件執行的命令。上面的「文件」和「1」不是實際的文件。如果文件名包含空格或逗號等內容,我該怎麼做?

這比我覺得有點棘手find -print0 | xargs -0可以處理,因爲我實際上想要的命令是類似「convert input/file1.jpg .... output/file1.jpg」,所以我需要在此過程中對文件名進行排列。

回答

2

更新通過OP:這個答案很爛,不應該在最上面...... @喬丹的帖子應該是被接受的答案。

一種可能的方式:

ls -1 | while read x; do 
    echo $x 
done 

+0

@ʞɔıu,如果答案是錯的,那麼你就可以取消接受它,這樣就不會誤導任何人。 – codeforester

+0

@codeforester - 我編輯說,答案吸了,而不是ʞɔıu。 – eduffy

8

事實上,馬克的建議,甚至沒有做任何內部字段分隔符工作正常。問題是在子shell中運行ls,無論是通過反引號還是$()​​導致for循環無法區分名稱中的空格。只需使用

for f in * 

而不是ls解決了問題。

#!/bin/bash 
for f in * 
do 
echo "$f" 
done 
+0

約旦,我沒有看到eduffy的解決方案的任何問題。我嘗試了文件中有空格的文件。實際上,ls -1並不創建子shell。它只是創建另一個過程,就是這樣。 – codeforester

+0

我同意,它適用於我。老實說,當我發表這個評論時,以及我從「Mark」中找不到的答案這一事實,我認爲有些背景已經丟失,可能會更有意義。 @ eduffy的解決方案很好,額外的過程不是一個巨大的交易,雖然如果自動化一個非常大的一套地點,/也許/它會稍微慢一點,但我懷疑它會永遠是一個真正的問題世界。 – Jordan

0

我知道這是一個早已過去「回答」,並與所有尊重eduffy,我想出了一個更好的辦法,我想我會分享它。

eduffy的回答是什麼「錯誤」並不是它錯了,而是它給我施加的是一個痛苦的限制:當ls的輸出被管道化時,有一個隱含的子殼創建,這意味着變量循環退出後,設置在循環內的設置會丟失。因此,如果你想寫一些更復雜的代碼,你會在臀部疼痛處理。

我的解決辦法是採取了「的ReadLine」 功能和寫程序了它在其中您可以指定你可能想要的任何具體的行號從任何給定函數調用的結果。 ......作爲一個簡單的例子,從eduffy的:

ls_output=$(ls -1) 
# The cut at the end of the following line removes any trailing new line character 
declare -i line_count=$(echo "$ls_output" | wc -l | cut -d ' ' -f 1) 
declare -i cur_line=1 
while [ $cur_line -le $line_count ] ; 
do 
    # NONE of the values in the variables inside this do loop are trapped here. 
    filename=$(echo "$ls_output" | readline -n $cur_line) 
    # Now line contains a filename from the preceeding ls command 
    cur_line=cur_line+1 
done 

現在成整齊的小包裝含有並能去你的shell代碼,而不必擔心你的變量的作用域你已經結束了所有的子shell活動價值陷入subhells。

我在gnuc寫了我的readline版本,如果有人想要一個副本,在這裏發佈有點大,但也許我們可以找到一種方法...

希望這有助於 RT