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

bmw*_*128 451 bash rename file-rename

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

我想把它们重命名为 *.txt

我使用bash shell.

gho*_*g74 641

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

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done
Run Code Online (Sandbox Code Playgroud)

  • 如果您不知道文件扩展名,可以使用"$ {file%.*}.txt"`,但这对于没有扩展名的文件可能会很危险. (8认同)
  • @danip百分比符号内括号构造从最后删除字符.还有一个hash-within-bracket结构,可以从头开始删除字符.检查一下:http://tldp.org/LDP/abs/html/parameter-substitution.html#PSUB2 (7认同)
  • 这也适用于`for*/*.html`中的文件 (6认同)
  • 我需要一种永久喜欢/书签这个答案的方法,我永远不会记住确切的语法,我最终谷歌搜索它 (5认同)
  • 另一个Stack交换答案(我找不到!)建议这个,但也使用`--`"运算符":mv - "$ file""$ {file%.html} .txt"该运算符阻止文件由mv作为参数解析的以' - '开头的名称. (4认同)
  • 请注意像我这样无法正常工作的任何人:注意花括号内没有`$`! (2认同)

Mik*_*uno 360

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


以下内容可以并且不需要系统具有该rename程序(尽管您通常在系统上具有此功能):

for file in *.html; do
    mv "$file" "$(basename "$file" .html).txt"
done
Run Code Online (Sandbox Code Playgroud)

编辑:正如评论中所指出的,如果没有适当的引用(现在在上面添加),这对于包含空格的文件名不起作用.当你纯粹在自己的文件上工作时,你知道文件名中没有空格,这可以工作,但是当你写一些可以在以后重复使用的东西时,不要跳过正确的引用.

  • 另一种选择,没有基本名称和带引号:mv"$ {file}""$ {file /%.html/.txt}"(有关详细信息,请参阅man bash,参数扩展) (46认同)
  • 当然,只有文件全部在当前目录中才有用,因为basename剥离了路径名部分.只是'小心'! (7认同)
  • 这个解决方案很糟糕,不仅因为它很慢,而且因为它不适用于带有空格的文件名.你应该总是在bash脚本中做正确的引用.mv"$ file""$(basename"$ file".html)".txt会好得多.但是,mv"$ files""$ {files%.html} .txt"要好得多. (6认同)
  • 在windows中你只需要`ren*.a*.b` (6认同)
  • 至少要使用POSIX指定的`$()`而不是旧的backtick语法。改进了可读性,并且当您有一些字符需要用反斜杠转义以在用后者替换的命令中成为原义时,该语法使语法少了很多。 (2认同)

Amb*_*ber 183

rename 's/\.html$/\.txt/' *.html
Run Code Online (Sandbox Code Playgroud)

完全符合你的要求.

  • bash,在Ubuntu(Jaunty). (2认同)

Ste*_*azo 100

这对我来说在OSX上从.txt到.txt_bak

find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;
Run Code Online (Sandbox Code Playgroud)

  • 在linux中工作正常. (4认同)
  • 这很适合递归重命名 (3认同)
  • 可以处理+6000个文件,重命名报告“参数列表过长” (2认同)

Dav*_*veR 91

你想用rename:

rename -S .html .txt *.html
Run Code Online (Sandbox Code Playgroud)

这不正是你想要的东西-这将延长从改变.html.txt的所有文件匹配*.html.

注意:Greg Hewgill正确地指出这不是一个bash内置; 并且是一个单独的Linux命令.如果你只需要Linux上的东西,这应该工作正常; 如果您需要更多跨平台的东西,那么请看一下其他答案.

  • "$ rename .html .txt*.html"导致...(#val 1)第1行的语法错误,靠近"." (15认同)
  • 正确的语法是`rename -S .html .text*.html`,其中`-S`代表`--subst-all` (8认同)
  • 虽然这是一个很好的解决方案,但`rename`程序与`bash`无关,也不适用于所有平台.我只在Linux上看过它. (7认同)
  • brew安装重命名 (7认同)
  • @GregHewgill重命名适用于带有HomeBrew的Mac OS (4认同)
  • 没有-S选项来重命名util-linux的2.28.2.但它没有它. (3认同)
  • 我的Ubuntu 16不包括-S用于重命名. (3认同)
  • 未知选项:ubuntu 上的 S (2认同)

izi*_*tti 35

在Mac上......

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


Bhe*_*har 15

对于Ubuntu用户:

rename 's/\.html$/\.txt/' *.html
Run Code Online (Sandbox Code Playgroud)


Har*_*rat 9

在Linux或window git bash或window的wsl中,尝试以下命令仅用一行代码更改当前目录或子目录甚至其子目录中的每个文件的扩展名

find . -depth -name "*.html" -exec sh -c 'mv "$1" "${1%.html}.txt"' _ {} \;
Run Code Online (Sandbox Code Playgroud)


bdo*_*bro 8

这是我发现适用于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' - '{}' \;


A.A*_*A.A 7

以下是重命名命令的示例:

rename -n ’s/\.htm$/\.html/’ *.htm
Run Code Online (Sandbox Code Playgroud)

-n表示它是一个测试运行,实际上不会更改任何文件.它将显示一个文件列表,如果删除了-n,将重命名这些文件.在上面的例子中,它会将当前目录中的所有文件从.htm的文件扩展名转换为.html.

如果上面测试运行的输出看起来没问题那么你可以运行最终版本:

rename -v ’s/\.htm$/\.html/’ *.htm
Run Code Online (Sandbox Code Playgroud)

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

$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html
Run Code Online (Sandbox Code Playgroud)

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

rename -v ’s/\.htm$/\.html/’ *.htm
Run Code Online (Sandbox Code Playgroud)


Mar*_*cos 5

在其他人的网站抓取之后,我最终在一个广泛的子目录树中找到了数千个缺少.html扩展名的文件.

要一次性重命名它们,除了已经有.html扩展名的文件(大多数都没有),这对我有用:

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

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

find . -xtype f  -iname *.txt   -exec filename="{}"  mv -iv ${filename%.*}.{txt,html}  \; 
Run Code Online (Sandbox Code Playgroud)

分解(hammertime!):

-iname*.txt
- 表示只考虑已经以.txt结尾的文件

mv -iv"{}.{txt,html}" - 当find以{}作为文件名传递时,$ {filename%.*}提取其基本名称而没有任何扩展名,以形成mv的参数.bash使用{txt,html}将其重写为两个参数,因此最终命令运行如下:mv -iv "filename.txt" "filename.html"

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


Mic*_*ard 5

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

zmv '(*).*' '$1.txt'
Run Code Online (Sandbox Code Playgroud)

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

autoload -U zmv
Run Code Online (Sandbox Code Playgroud)

然后再试一次.

感谢这篇关于zmv的原始文章.


Rok*_*jic 5

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

mmv ";*.xml" "#1#2.html"
Run Code Online (Sandbox Code Playgroud)

;将匹配的路径时,*将匹配的文件名,并且这些称作#1#2在替换名称。

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


Chr*_*rno 5

一行,没有循环:

ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
Run Code Online (Sandbox Code Playgroud)

例子:

$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json  ac8453e2-0d82-4d43-b80e-205edb754700.json
$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt  ac8453e2-0d82-4d43-b80e-205edb754700.txt
Run Code Online (Sandbox Code Playgroud)