如何在当前目录的所有文件名中用一个字符替换另一个字符?


41

如何重命名当前文件夹中的所有文件/子目录?

可以说,我有很多带有空格的文件和子目录,我想用下划线替换所有空格。

File 1
File 2
File 3
Dir 1
Dir 3

应该重命名为

File_1
File_2
File_3
Dir_1
Dir_3

Answers:


36

如果您还需要在子目录中重命名文件,并且您find支持-execdir谓词,那么您可以执行

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

感谢@glenn jackman提出的建议-depth选项,find并让我思考。

请注意,在某些系统(包括GNU / Linux的系统)上,find可能无法找到名称中包含空格以及不构成有效字符的字节序列的文件(通常对于名称以字符集编码的非ASCII字符的媒体文件而言)与语言环境不同)。将语言环境设置为C(如中所示LC_ALL=C find...)将解决该问题。


您将需要使用find -maxdepth 1OP完全按照OP要求对当前文件夹进行操作。
迦勒(Caleb)

1
使用find的-depth选项,您可以摆脱sort
glenn jackman 2011年

@glenn jackman:谢谢,我现在知道我的解决方案是错误的。
enzotib

2
更改-name '* *'-name '*_*'和变革"${1// /_}""${1//_/.}"
enzotib

1
@kroiz:它称为“图案替换”。您可以在bash的手册页中找到它。
enzotib

34

在任何外壳程序中,您都可以遍历名称包含空格的文件。在bash,ksh和zsh中,使用下划线替换空格很容易${VARIABLE//PATTERN/REPLACEMENT}

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

在Debian,Ubuntu和衍生产品上,您可以使用Perl rename(其他发行版提供的其他程序与一样rename,但该程序在这里没有帮助)。

rename 's/ /_/g' *

强制性的zsh解决方案:

autoload zmv
zmv '(*)' '${1// /_}'

强制性POSIX解决方案:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done

“重命名”命令末尾的“ g”是什么意思?我在手册中没有看到它。
朱利安

如何仅重命名目录?我不想更改文件名。
朱利安

@JulianLai s/…/…/g表示替换所有出现的情况。手册中没有很好解释。如果您想重命名目录,可以通过多种方法进行搜索(我想我以前已经看过),如果找不到它,请提出一个新问题。
吉尔斯(Gillles)“所以别再邪恶了”

太棒了...这帮助我将所有名称重命名_MG_blah.JPGIMG_blah.JPG
Abinash Dash

13

您可以使用rename它(此处假设来自util-linux而不是perl):

cd /path/to/dir
rename ' ' _ *\ *

这将在名称中找到所有文件和目录空间,并用下划线替换该空间。由于它使用glob文件匹配,因此您需要在正确的目录中开始。

如果您想进行递归匹配,则可以,但是您可能必须执行rename几次才能捕获自己重命名的目录中的所有项目:

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!

2
rename将通过更换命名指定的文件中第一次出现由他们的名字。”因此,这将仅适用于文件,在他们的名字一个单一的空间工作。(您可以调用rename一个循环,但这并不是真正合适的工具。)
吉尔斯(Gills

2

mmv如果已安装,则另一个选项是。

mmv \*\ \* \#1_#2

这只会将第一个空格更改为_,不适用于多个空格的名称。
吉尔(Gilles)'所以

糟糕,您是对的。对困惑感到抱歉。
glglgl

1

在Debian / Ubuntu上,基于Caleb和Gilles的答案,这就是我递归重命名文件的方法:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

注意:要预览将重命名哪些文件以及如何重命名,请使用-n带有的开关rename

rename -n 's/ /_/g' **

另一个注意事项:设置globstar**在所有子目录中创建匹配文件,因此,如果只需要当前目录,请不要设置globstar或使用*代替**

另一个注意事项:rename对于多次出现搜索词的文件,该命令需要多次运行。


仅在目录不包含空格的情况下才有效。(中重命名a b/c da_b/c_d是行不通的,你需要先重命名a b/c da b/c_d,然后a ba_b)。
斯特凡Chazelas

@Stephane:这意味着rename两次运行同一命令吗?
Markus Pscheidt

好吧,与嵌套目录级别的空格一样多。理想情况下,您要先遍历目录深度,然后像接受的解决方案一样仅转换文件的基本名称。还要注意,bash的**排除点文件,并遍历符号链接。
斯特凡Chazelas

0

如果您不是正则表达式的专家(我不是!),并且可以运行为kde设计的应用程序(使用kde-k桌面或安装了库),则krename是一个很棒的图形实用程序,让您在之前和之后看到之前您提交的变化。它具有许多作为选项的简单转换,还支持正则表达式。您甚至可以将几个顺序的转换组合到一个重命名中,因此您不必设计一次即可完成所有操作的复杂转换。它也具有在应用重命名后继续重命名相同文件的选项。

我不经常使用它,但是当我这样做时,它确实可以快速轻松地完成工作。重命名各种下载的媒体文件时,它确实非常方便,因此您可以在系统上对其进行统一管理。这有助于单独下载krename手册,以便您在使用程序时可以参考它。

http://www.krename.net/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.