如何更改多个文件的扩展名?


166

我想将文件扩展名从更改*.txt*.text。我尝试使用该basename命令,但是在更改多个文件时遇到了麻烦。

这是我的代码:

files=`ls -1 *.txt`

for x in $files
do
    mv $x "`basename $files .txt`.text"
done

我收到此错误:

basename: too many arguments Try basename --help' for more information

Answers:


175

直接来自Greg的Wiki

#将所有* .txt重命名为* .text
对于* .txt中的f;做
    mv-“ $ f”“ $ {f%.txt} .text”
完成

另请参阅有关为什么不应该分析ls的条目。

编辑:如果您必须使用basename您的语法将是:

对于* .txt中的f;做
    mv-“ $ f”“ $(基本名称-” $ f“ .txt).text”
完成

48
这里使用了一些稍微高级的Bash语法,没有说明。我必须对Google做很多事情才能完全理解这一点。为了帮助别人在我的位置上,这里有关于一些参考水珠(的*.txt语法),该裸双破折号--,并在内部使用%符号的${}结构。到现在为止,我从未遇到过后两者,并且不知道前者真正发生了什么。
Mark Amery 2014年

3
请看下面Matthias Braun的答案-简单得多,完成同样的事情。
btk 2015年

10
一个班轮for f in *.txt; do mv -- "$f" "${f%.txt}.text"; done
马萨尔胡安

1
你失踪了; 文字之后”。
PéturIngi Egilsson

2
@PéturIngiEgilsson在第二行?不,不是必需的。
jasonwryan

132

这是我更改Debian当前目录中所有文件扩展名的方法。

rename "s/oldExtension/newExtension/" *.txt

(这是Perl rename命令,不是Perl 命令util-linux。请参见为什么Debian / Ubuntu上的重命名实用程序与其他发行版(例如CentOS上的重命名实用程序不同?


10
比接受的答案简单得多,谢谢!
btk 2015年

8
在Mac上,我能够brew install rename并使其正常工作。
Monkpit '16

3
rename "s/oldExtension/newExtension/" **.txt
鱼壳,

3
这将失败footxt.txt。改用它:unix.stackexchange.com/questions/19654/…–
wisbucky

7
当您的文件没有任何扩展名而您想要添加一个扩展名时:rename 's/$/.txt/' *
mkataja

34

一个简单的命令renamefromutil-linux,将为您完成此操作,它将所有匹配“ * .txt”的文件中所有出现的“ txt”替换为“ text”:

rename txt text *.txt

4
rename更改第一次出现的位置,因此最好使它发生变化rename .txt .text,但这仍然不能总是起作用(例如,将其重命名foo.txtx.bar.txtfoo.textx.bar.txt)。
吉尔斯

12
应该注意的是,并不是所有的系统都具有相同的重命名版本。在Debian和朋友上,该rename命令实际上是perl-rename使用perl正则表达式的。为此,等效命令为:rename 's/.txt/.text/' *.txt。人们应该检查man rename他们的系统,以找出拥有的系统。
evilsoup

@evilsoup OSX就是这样
Davi Lima

这也适用于Cygwin(Windows)
Andy

27
rename "s/oldExtension/newExtension/" *.txt

以上工作正常,但仅限于当前目录。请尝试以下命令,该命令对于子目录很灵活。它将.txt使用新扩展名重命名目录结构下的所有文件。

find . -name "*.txt" -exec rename 's/.txt$/.newext/' {} \;

2
rename可以处理多个文件作为参数,您可以使用+而不是\;如果有很多这样的文件来极大地加快处理速度
Anthon 2015年

不过,这是一个有用的选项,因为“ * .txt”可以展开到外壳程序不支持的大参数列表。
罗曼·夏波娃洛夫

1
的“ s / oldExtension / newExtension /”将失败footxt.txt。改用它:unix.stackexchange.com/questions/19654/…–
wisbucky


9

这里引用的答案s/oldExtension/newExtension/是错误的。如果使用s/txt/text/,则将转换footxt.txtfootext.txt,这不是您想要的。即使您使用s/.txt/.text/,也将转换footxt.txtfo.text.txt

您必须使用\.匹配句点(.将匹配任何字符)。和尾随$以匹配行的结尾。只有这样才能正确匹配扩展名。

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

rename 's/\.old$/.new/' *.old

7

基于@Prince John Wesley的答案,这是一个简单的bash脚本,用于将当前目录中文件的所有扩展名从ext1更改为ext2。还输出要重命名的文件的名称。

#!/bin/bash
for f in *.$1
do
    [ -f "$f" ] && mv -v "$f" "${f%$1}$2"
done

示例用法(假设脚本的名称change-ext):

change-ext ext1 ext2

要递归更改目录中文件的扩展名,请将第二行(for...)替换为两行:shopt -s globstarfor f in **/*.$1。需要Bash 4+。
丹尼斯·戈洛马佐夫


3

假设您的文件分散在各个目录中,假设dirx是您的父目录,则可以使用find执行此操作:

for f in `find /dirx -iname '*.txt' -type f -print`;do  mv "$f" ${f%.txt}.text; done


2

这对我有用:

find . -name '*.txt' -exec rename 's/\.txt$/.text/' \{} \;

1
请添加一个。在“文本”之前
danielmhanover

2

当你

没有源文件的扩展名

而目标扩展名是.text,您可以通过以下方式进行操作-

for f in *; do mv -- "$f" "${f%.\*}.text"; done

1
出色的bash原生脚本。很棒!for f in *.html; do mv -- "$f" "${f%.\*}.pug"; done
TamusJRoyce

1

如果您想知道版本中出了什么问题:您使用$files而不是$xbasename命令。因此,这应该起作用(不过,未经测试):

for x in *.txt
do
  mv "$x" "`basename '$x' .txt`.text"
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.