使用一个命令重命名一组文件


38

如果我有一组扩展名为.htm的文件,如何将它们全部重命名为.html?

mv *.htm *.html

不起作用。


仅出于完整性考虑,ren *.htm *.html将在Windows中运行。
Brian Burns

Answers:


50

或者,您可以使用纯bash ...(除mv以外,就是..)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

并避免使用讨厌的基本名称。;)

Bash具有广泛的变量扩展选项集。此处使用的一个'%'从变量值中删除最小的匹配后缀。该模式是全局模式,因此${file%.*}也可以使用。'%%'运算符删除了最大的匹配后缀,并且在上面的示例中可以互换,因为该模式是固定的,${file%%.*}.html但是会将abhtm转换为a.html。

有关更多巧妙的技巧,请参见bash联机帮助页的变量替换部分。直接在bash中可以做很多事情。


1
还要注意,这些参数扩展不限于bash。它们可用于所有Bourne衍生的shell(shkshbashzshdashash等)。扩展是“ Shell命令语言”的POSIX规范的一部分,具有高度的可移植性。
克里斯·约翰森

11

文件名中不应包含空格,换行符或其他空格,但是此版本的freiheit的答案可以解决这些问题。它还使用$()反引号代替了可读性以及其他优点。

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

甚至更好-对于仅添加到最后的特殊情况:

for file in *.htm
do
    mv "$file" "${file}l"
done

11

rename(1)是一个Perl实用程序,可以完全满足您的需求。在这种情况下:

rename 's/\.htm$/.html/' *htm

或者如果您也在使用子目录

(需要猛砸4.0和globstar设置:shopt -s globstar

rename 's/\.htm$/.html/' **/*htm


1
重命名比较容易,但不是标准的Unix程序;原始问题未指定哪个Unix。在某些地方似乎是“姓氏”。
自由报

2
rename随Perl一起提供,并且这些天基本上每个unix都随Perl一起提供。
TRS-80

3
是的,但是当每个unix将perl放在系统中时,并不是每个unix都包含诸如“重命名”之类的辅助程序。例如,OSX上没有“重命名”。
自由报

1
@William:双星号语法仅在Bash 4及更高版本中可用,并且仅在打开时启用shopt -s globstar(默认为关闭)。另外,Linux和Unix具有目录而不是文件夹。
暂停,直到另行通知。

6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

与尝试它echo在前面mv第一次左右。

原始文件的问题是“ mv *.htm *.html*由外壳程序处理了,因此该mv命令仅查看当前目录中所有.htm和.html文件的列表。换句话说,类似“ mv foo.htm bar.htm stuff.htm six.htm file.htm”。如果最后一个是目录,则mv仅知道如何处理2个以上的参数。


1
您应该引用“ $ file”来处理空格。
理查德·霍斯金斯

您应该更加强调您对原始问题的描述。Shell的通配符扩展行为对于来自Windows领域的人来说是令人惊讶且不直观的,并且了解Shell的功能可以清楚地说明为什么原始应用程序mv无法正常工作。
格雷格·休吉尔

3

另一个使用字符串替换的纯bash示例。

for file in *.htm; do mv $file ${file/htm/html}; done

额外-替换所有出现的字符串

for file in *.htm; do mv $file ${file//htm/html}; done



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.