2016-03-16 31 views
0

這是我想到一個bash循環測序輸出:意外序列

for i in $(seq 2); do 
    echo $i 
    echo $(expr $i + 10) 
done 
1 
11 
2 
12 

這是怎麼了遞歸文件夾文件操作順序:

for file in "$(find . -name '*.txt')"; do 
    echo "$file"; 
    newfile="${file//\.txt/.csv}" 
    echo "$newfile"; 
    mv '$file' '$newfile' 
done 
./dir1/a.txt 
./dir2/b.txt 
./dir2/dir3/c.txt 
./dir1/a.csv 
./dir2/b.csv 
./dir2/dir3/c.csv 
mv: rename $file to $newfile: No such file or directory 

我我嘗試了mv調用名稱變量包裝"和沒有引號,它會返回不同的錯誤。

感謝指點,我要去錯了。

+1

這[不讀取用線'for'](http://mywiki.wooledge.org/DontReadLinesWithFor)和連接的(從那裏)[擊FAQ 001](HTTP:// mywiki .wooledge.org/BashFAQ/001)討論了更適當的方法來逐行讀取數據。 –

回答

3

不應該在$(find)命令周圍引用引號:引號會導致將所有文件名連接成一個大字符串。 mv命令中的引號應該是雙引號:變量不會在單引號內部擴展。

for file in $(find . -name '*.txt'); do 
    echo "$file" 
    newfile="${file//\.txt/.csv}" 
    echo "$newfile" 
    mv "$file" "$newfile" 
done 

這不是通過文件列表循環的最佳方式。它會絆住任何帶空格的文件名。更好的方法是將find管道read循環。

find . -name '*.txt' | while read file; do 
    ... 
done 

這將處理大多數文件的罰款。它仍然會遇到帶前導空格,反斜槓或嵌入換行符的文件(這在技術上是合法的)。爲了處理這些:

find . -name '*.txt' -print0 | while IFS= read -r -d $'\0' file; do 
    ... 
done 

-print0-d $'\0'照顧換行符。 IFS=保持讀取領先的空白。 -r告訴它不要專門解釋反斜槓。

對於什麼是值得的,..txt不需要轉義。 .在這裏不是特殊字符。並且/%會比//更好,因爲替換應該只在字符串的末尾完成。

newfile=${file/%.txt/.csv} 
+2

這就是我正在循環。謝謝約翰 – geotheory

+0

像這個答案和那個評論。 – trojanfoe