2016-03-16 35 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