递归地重命名文件并删除字符

时间:2021-02-23 10:33:52

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

3 个解决方案

#1


1  

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

$的档案(请找到文件夹名称“*.mp3”);mv -v“$file”$(echo“$file”| tr)_);完成


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

找到文件夹- name”*。mp3' -exec echo "'{} " \;|在阅读文件;echo -n "mv -v $file " & echo $file | tr ?_;做|上海

The idea is to find all the files, then echo them in quotes. Pipe the output into a while loop that constructs a mv command for each file, and then pipe that into a new shell.

我们的想法是找到所有的文件,然后用引号将它们重复。将输出导入一个while循环,该循环为每个文件构造一个mv命令,然后将其导入一个新的shell。

Ugly, but if you don't like the answer, you shouldn't have asked the question. :-)

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

#2


1  

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

找到文件夹- name”*。mp3 - exec \ sh - c”echo - n ' mv \“{ } \”& &回声\“{ } \ | tr”呢?_“\;|上海

The strategy is to find the files, use echo to construct a mv command for each file with its name in quotes, and then pipe the output to a shell.

策略是找到文件,使用echo为每个文件构造一个mv命令,每个文件的名称都用引号括起来,然后将输出传输到shell中。

#3


0  

This one-liner should work even if filenames contain single/double quotes and spaces:

即使文件名包含单/双引号和空格,这个一行仍然可以工作:

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

Explanation:

解释:

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

#1


1  

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

$的档案(请找到文件夹名称“*.mp3”);mv -v“$file”$(echo“$file”| tr)_);完成


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

找到文件夹- name”*。mp3' -exec echo "'{} " \;|在阅读文件;echo -n "mv -v $file " & echo $file | tr ?_;做|上海

The idea is to find all the files, then echo them in quotes. Pipe the output into a while loop that constructs a mv command for each file, and then pipe that into a new shell.

我们的想法是找到所有的文件,然后用引号将它们重复。将输出导入一个while循环,该循环为每个文件构造一个mv命令,然后将其导入一个新的shell。

Ugly, but if you don't like the answer, you shouldn't have asked the question. :-)

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

#2


1  

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

找到文件夹- name”*。mp3 - exec \ sh - c”echo - n ' mv \“{ } \”& &回声\“{ } \ | tr”呢?_“\;|上海

The strategy is to find the files, use echo to construct a mv command for each file with its name in quotes, and then pipe the output to a shell.

策略是找到文件,使用echo为每个文件构造一个mv命令,每个文件的名称都用引号括起来,然后将输出传输到shell中。

#3


0  

This one-liner should work even if filenames contain single/double quotes and spaces:

即使文件名包含单/双引号和空格,这个一行仍然可以工作:

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

Explanation:

解释:

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