关于bash:如何重命名一批文件的扩展名?

How do I rename the extension for a batch of files?

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

我想把它们全部改名为*.txt

我用巴什壳。


如果使用bash,则不需要外部命令,如sed、basename、rename、expr等。

1
2
3
4
for file in *.html
do
  mv"$file""${file%.html}.txt"
done


要获得更好的解决方案(只有bash功能,而不是外部调用),请参阅其他答案之一。

以下操作可以并且不需要系统具有rename程序(尽管您通常会在系统上使用此程序):

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

编辑:正如注释中指出的,如果文件名中没有适当的引用(现在已在上面添加),则不适用于其中包含空格的文件名。当您只处理自己的文件时,您知道文件名中没有空格,这将起作用,但当您编写一些稍后可能重用的内容时,不要跳过适当的引用。


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

做你想要的。


这对我在osx上从.txt到.txt的效果很好

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


您要使用rename

1
rename -S .html .txt *.html

这完全符合您的要求—它会将所有与*.html匹配的文件的扩展名从.html更改为.txt

注意:GregHewgill正确地指出,这不是bash内置的,而是一个单独的linux命令。如果您只需要Linux上的一些东西,这应该可以很好地工作;如果您需要更多跨平台的东西,那么看看其他的答案之一。


在Mac上…

  • 如果没有安装重命名:brew install rename
  • rename -S .html .txt *.html

  • 对于Ubuntu用户:

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


    下面是rename命令的示例:

    1
    rename -n ’s/\.htm$/\.html/*.htm

    -n意味着它是一个测试运行,实际上不会更改任何文件。它将显示如果删除-n将被重命名的文件列表。在上面的情况下,它将把当前目录中的所有文件从.htm扩展名转换为.html。

    如果上述测试运行的输出看起来正常,则可以运行最终版本:

    1
    rename -v ’s/\.htm$/\.html/*.htm

    -v是可选的,但最好包含它,因为它是您将要对rename命令所做更改的唯一记录,如下面的示例输出所示:

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

    中间比较棘手的部分是用正则表达式替换Perl,突出显示如下:

    1
    rename -v ’s/\.htm$/\.html/*.htm

    这个问题明确地提到了bash,但是如果您碰巧有zsh可用,那么非常简单:

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

    如果你得到了zsh: command not found: zmv,那么只需运行:

    1
    autoload -U zmv

    然后再试一次。

    感谢这篇关于ZMV的原创文章。


    在别人的网站爬行之后,我发现有数千个文件没有扩展名为.html,它们跨越了一个很宽的子目录树。

    要一次性重命名所有文件,除了已经具有.html扩展名的文件(大多数文件根本没有扩展名),这对我很有用:

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

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

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

    故障(HammerTime!):

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

    mv-iv".txt,html"-当find将作为文件名传递时,$filename%.*提取其basename,不带任何扩展名,以将参数形成mv。bash使用txt,html将其重写为两个参数,因此最后的命令运行为:mv -iv"filename.txt""filename.html"

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


    这是我发现的最灵活的解决方案,可以在OSX和Linux上使用,它也可以很好地与Git配合使用!

    find . -name"*.js" -exec bash -c 'mv"$1""${1%.js}".tsx' - '{}' \;

    与Git:

    find . -name"*.js" -exec bash -c 'git mv"$1""${1%.js}".tsx' - '{}' \;


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

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

    ;与路径匹配,*与文件名匹配,在替换名中称为#1#2

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


    参加聚会有点晚。您可以使用xargs:

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

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

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


    试试这个

    1
    rename .html .txt *.html

    用途:

    1
    rename [find] [replace_with] [criteria]


    如果您喜欢Perl,那么有一个简短的Perl脚本(最初由Perl的创建者Larry Wall编写)可以完全满足您的需要:tips.webdesign10.com/files/rename.pl.txt。在您的示例中,下面的技巧应该是

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

    =)

    (感谢@loretoparisi提供更新的网址)


    这是一次修改多个扩展的好方法:

    1
    2
    3
    4
    for fname in *.{mp4,avi}
    do
       mv -v"$fname""${fname%.???}.mkv"
    done

    注意:请注意延长件的尺寸要相同(是???)


    不幸的是,便携操作并不容易。你可能需要一点expr魔法。

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

    一旦你高兴了,就把回声移走,它会做你想做的。

    编辑:basename对于这个特定的案例可能更容易阅读,尽管expr在一般情况下更灵活。


    很好,很简单!

    1
    find . -iname *.html  -exec mv {}"$(basename {} .html).text"  \;

    这是我用来将.edge文件重命名为.blade.php的文件。

    1
    for file in *.edge; do     mv"$file""$(basename"$file" .edge).blade.php"; done

    很有魅力。