【发布时间】:2020-08-31 09:38:30
【问题描述】:
我想替换文件名中的空格。我的测试目录包含带空格的文件:
$ ls
'1 2 3.txt' '4 5.txt' '6 7 8 9.txt'
例如,这段代码可以正常工作:
$ printf "$(printf 'spaces in file name.txt' | sed 's/ /_/g')"
spaces_in_file_name.txt
我将下划线和命令替换上的空格替换为双引号作为文本。这种具有重要替换的构造在下一种情况下是必不可少的。 find 和 xargs 等命令具有像 {}(大括号)这样的替换标记。因此下一条命令可以替换文件中的空格。
$ find ./ -name "*.txt" -print0 | xargs --null -I '{}' mv '{}' "$( printf '{}' | sed 's/ /_/g' )"
mv: './6 7 8 9.txt' and './6 7 8 9.txt' are the same file
mv: './4 5.txt' and './4 5.txt' are the same file
mv: './1 2 3.txt' and './1 2 3.txt' are the same file
但我得到错误。为了更清楚地考虑错误,我只使用 echo(或 printf)代替 mv:
$ find ./ -name "*.txt" -print0 | xargs --null -I '{}' echo "$( printf '{}' | sed 's/ /_/g' )"
./6 7 8 9.txt
./4 5.txt
./1 2 3.txt
正如我们所见,下划线没有替换空格。但如果没有命令替换,替换将是正确的:
$ find ./ -name "*.txt" -print0 | xargs --null -I '{}' printf '{}\n' | sed 's/ /_/g'
./6_7_8_9.txt
./4_5.txt
./1_2_3.txt
所以命令替换大括号的事实是破坏结果(因为在第一个命令是正确的结果),但没有命令替换结果是正确的。但是为什么???
【问题讨论】: