bash 递归重命名文件并删除一个字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10162537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
recursively rename files and remove a character
提问by mahmood
There are some file names which contain '?'
As you know windows has problem with such characters. I want to recursively rename all files in the folders using xarg. For example
有一些文件名包含“?” 如您所知,Windows 对此类字符存在问题。我想递归地重命名文件夹中的所有文件xarg。例如
09 - grand hall?_10.mp3
should be
应该
09 - grand hall_10.mp3
采纳答案by Adam Liss
for file in $(find folder-name '*.mp3'); do
mv -v "$file" $(echo "$file" | tr ? _);
done
for file in $(find folder-name '*.mp3'); do
mv -v "$file" $(echo "$file" | tr ? _);
done
The above has whitespace issues; this is better:
以上有空格问题;这个更好:
find folder-name '*.mp3' -exec echo "'{}'" \; |
while read file; do
echo -n "mv -v $file " && echo $file | tr ? _;
done | sh
find folder-name '*.mp3' -exec echo "'{}'" \; |
while read file; do
echo -n "mv -v $file " && echo $file | tr ? _;
done | sh
The idea is to find all the files, then echo them in quotes. Pipe the output into a whileloop that constructs a mvcommand for each file, and then pipe thatinto a new shell.
这个想法是找到所有文件,然后用引号将它们回显。管的输出成一个while循环,构建了一个mv命令为每个文件,然后通过管道即进入一个新的壳。
Ugly, but if you don't like the answer, you shouldn't have asked the question. :-)
丑,但如果你不喜欢这个答案,你就不应该问这个问题。:-)
回答by Adam Liss
This is terribly ugly, but I took it as a personal challenge to find a one-liner that would work. :-)
这是非常丑陋的,但我把找到一个可行的单线作为个人挑战。:-)
find folder-name '*.mp3' -exec \
sh -c "echo -n 'mv \"{}\" ' && echo \'{}\' | tr ? _" \; | sh
find folder-name '*.mp3' -exec \
sh -c "echo -n 'mv \"{}\" ' && echo \'{}\' | tr ? _" \; | sh
The strategy is to find the files, use echoto construct a mvcommand for each file with its name in quotes, and then pipe the output to a shell.
策略是找到文件,用引号为每个文件echo构造一个mv命令,然后将输出通过管道传输到 shell。
回答by Hui Zheng
This one-liner should work even if filenames contain single/double quotes and spaces:
即使文件名包含单/双引号和空格,这种单行也应该有效:
(IFS=##代码##;find . -name \*\?\* -type f -print0| while read -d '' f;do mv -v $f $(echo $f|tr -d \?);done)
Explanation:
解释:
findonly search files whose names contain '?'- setting
\0as delimiter inIFS,find(by-print0) andread(by-d '') can handle filenames containing special characters like single quotes, double quotes, spaces, etc. - the outmost parenthese puts the entire command execute in subshell, hence keeps the current shell's
IFSintact. - The
.in the script could be replaced by any other directory. - This script has a very tiny catch, though: it may break if both a file's name and one of its parents' name contains '?'. This could be handled, but the script will become a little uglier and less readable.
find只搜索名称包含“?”的文件\0在IFS,find(by-print0) 和read(by-d '') 中设置为分隔符可以处理包含特殊字符的文件名,如单引号、双引号、空格等。- 最外面的括号将整个命令放在子 shell 中执行,因此保持当前 shell 的
IFS完整。 - 该
.脚本可以被任何其他目录来代替。 - 不过,这个脚本有一个非常小的问题:如果文件名和其中一个父文件名都包含“?”,它可能会中断。这可以处理,但脚本会变得更难看,可读性更低。

