2

有一些文件名包含“?” 如您所知,Windows 存在此类字符的问题。我想使用递归重命名文件夹中的所有文件xarg。例如

09 - grand hall?_10.mp3

应该

09 - grand hall_10.mp3
4

3 回答 3

2

for file in $(find folder -name '*.mp3'); do
  mv -v "$file" $(echo "$file" | tr ? _);
done


以上有空格问题;这个更好:

find folder -name '*.mp3' -exec echo "'{}'" \; |
  while read file; do
    echo -n "mv -v $file " && echo $file | tr ? _;
done | sh

这个想法是找到所有文件,然后用引号回显它们。将输出传递到为每个文件while构造mv命令的循环中,然后将其传递新的 shell 中。

丑陋,但如果你不喜欢这个答案,你就不应该问这个问题。:-)

于 2012-04-15T13:54:04.153 回答
1

这非常难看,但我认为找到一个可行的单线是一种个人挑战。:-)

find folder -name '*.mp3' -exec \
  sh -c "echo -n 'mv \"{}\" ' && echo \'{}\' | tr ? _" \; | sh

策略是找到文件,用引号为每个文件echo构造一个mv命令,然后将输出通过管道传输到 shell。

于 2012-04-15T13:48:37.567 回答
0

即使文件名包含单/双引号和空格,这个单行也应该工作:

(IFS=\0;find . -name \*\\?\* -type f -print0| while read -d '' f;do mv -v $f $(echo $f|tr -d \?);done)

解释:

  1. find仅搜索名称包含“?”的文件
  2. 在, (by ) 和(by ) 中设置\0为分隔符可以处理包含特殊字符的文件名,如单引号、双引号、空格等。IFSfind-print0read-d ''
  3. 最外面的括号将整个命令放在子 shell 中执行,因此保持当前 shell 的IFS完整。
  4. 脚本中的.可以替换为任何其他目录。
  5. 不过,这个脚本有一个非常小的问题:如果文件名和它的父名之一都包含“?”,它可能会中断。这可以处理,但脚本会变得有点丑陋和可读性差。
于 2012-04-15T16:34:22.267 回答