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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:01:42  来源:igfitidea点击:

recursively rename files and remove a character

linuxbashrenamexargs

提问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:

解释:

  1. findonly search files whose names contain '?'
  2. setting \0as delimiter in IFS, find(by -print0) and read(by -d '') can handle filenames containing special characters like single quotes, double quotes, spaces, etc.
  3. the outmost parenthese puts the entire command execute in subshell, hence keeps the current shell's IFSintact.
  4. The .in the script could be replaced by any other directory.
  5. 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.
  1. find只搜索名称包含“?”的文件
  2. \0IFS, find(by -print0) 和read(by -d '') 中设置为分隔符可以处理包含特殊字符的文件名,如单引号、双引号、空格等。
  3. 最外面的括号将整个命令放在子 shell 中执行,因此保持当前 shell 的IFS完整。
  4. .脚本可以被任何其他目录来代替。
  5. 不过,这个脚本有一个非常小的问题:如果文件名和其中一个父文件名都包含“?”,它可能会中断。这可以处理,但脚本会变得更难看,可读性更低。