bash递归循环中的意外序列

时间:2016-03-16 12:40:17

标签: macos bash

这就是我期望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 个答案:

答案 0 :(得分: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}