如何重命名一批文件的扩展名?

在一个目录中,我有一堆*.html文件。

我想将它们全部重命名为*.txt

我使用bash shell。

为了更好的解决scheme(只有bashfunction,而不是外部调用),请参阅其他答案之一 。


以下将做,并不需要系统有rename程序(虽然你最常在系统上有这个):

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

编辑:正如在评论中指出的,这不适用于没有正确的引号(现在上面添加)的空格在文件名。 当纯粹使用你自己的文件,你知道文件名中没有空格的时候,这个文件可以工作,但是每当你写了一些可能在以后重用的文件时,不要跳过适当的引用。

如果使用bash,不需要像sed,basename,rename,expr等等的外部命令

 for file in *.html do mv "$file" "${file%.html}.txt" done 
 rename 's/\.html$/\.txt/' *.html 

正是你想要的。

你想使用rename

 rename -S .html .txt *.html 

这正是你想要的 – 它会将所有匹配*.html文件的扩展名从.html改为.txt

注意:格雷格Hewgill正确地指出,这不是一个bash内build; 并且是一个单独的Linux命令。 如果你只是需要Linux上的东西,这应该工作得很好; 如果你需要更多的跨平台的话,请看看其他的答案。

这在我的OSX上从.txt到.txt_bak

 find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \; 

在Mac上…

  1. 安装重命名,如果你还没有: brew install rename
  2. rename -S .html .txt *.html

对于Ubuntu用户:

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

以下是重命名命令的一个例子:

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

-n意味着它是一个testing运行,并不会真正改变任何文件。 它会显示一个文件列表,如果您删除了-n,那么这些文件将被重命名。 在上面的例子中,它会将当前目录中的所有文件从.htm文件扩展名转换为.html。

如果上面的testing运行的输出看起来不错,那么你可以运行最终版本:

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

-v是可选的,但包含它是一个好主意,因为它是唯一的logging,您将通过rename命令进行更改,如下面的示例输出中所示:

 $ rename -v 's/\.htm$/\.html/' *.htm 3.htm renamed as 3.html 4.htm renamed as 4.html 5.htm renamed as 5.html 

中间的棘手部分是使用正则expression式的Perlreplace,如下所示:

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

在别人的网站抓取后,我结束了数以千计的文件缺less.html扩展名,横跨一个广泛的子目录树。

除了已经有一个扩展名为.html的文件(大部分没有任何文件)之外,要将它们全部重命名为一次,这对我来说很有效:

 cd wwwroot find . -xtype f \! -iname *.html -exec mv -iv "{}" "{}.html" \; # batch rename files to append .html suffix IF MISSING 

在OP的情况下,我可能稍微修改,只重命名* .txt文件,如下所示:

 find . -xtype f -iname *.txt -exec filename="{}" mv -iv ${filename%.*}.{txt,html} \; 

分解(寒假!):

-iname * .txt
– 意味着只考虑已经以.txt结尾的文件

mv -iv“{}。{txt,html}” – 当find传递一个{}作为文件名时,$ {filename%。*}提取它的基本名而不用任何扩展名来形成mv的参数。 bash以{txt,html}将其重写为两个参数,所以最终的命令运行如下: mv -iv "filename.txt" "filename.html"

虽然需要修复:处理文件名中的空格

尝试这个

 rename .html .txt *.html 

用法:

 rename [find] [replace_with] [criteria] 

晚会有点晚了 你可以用xargs做到这一点:

 ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {} 

或者如果你所有的文件都在某个文件夹中

 ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {} 

不幸的是,这不是轻而易举的事情。 你可能需要一点expr魔法。

 for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done 

一旦你开心,删除回声它做你想做的。

编辑: basename可能是这个特定情况下更易读,虽然expr更灵活一般。

如果您更喜欢PERL,那么会有一个很短的PERL脚本(由PERL的创build者Larry Wall执笔),它将完成您想要的function: tips.webdesign10.com/files/rename.pl.txt 。 对于你的例子,以下应该做的伎俩

rename.pl 's/html/txt/' *.html

=)

(感谢@loretoparisi更新的url)

这个问题明确提到了Bash,但是如果你碰巧有ZSH可用的话,这很简单:

 zmv '(*).*' '$1.txt' 

如果你zsh: command not found: zmv那么只需运行:

 autoload -U zmv 

然后再试一次。

感谢这篇关于zmv的小贴士。

命令mmv似乎在大量文件(每秒几万次)上非常有效地完成了这项任务。 例如,要将所有.xml文件重命名为.html文件,请使用以下命令:

 mmv ";*.xml" "#1#2.html" 

; 将匹配path, *将匹配文件名,并且这些在replace名称中被称为#1#2

基于exec或pipe道的答案要么太慢,要么在很大数量的文件上失败。