在一个目录中,我有一堆*.html文件。
我想把它们全部改名为*.txt。
我用巴什壳。
如果使用bash,则不需要外部命令,如sed、basename、rename、expr等。
1 2 3 4
| for file in *.html
do
mv"$file""${file%.html}.txt"
done |
- 这也适用于for files in */*.html。
- 如果您不知道文件扩展名,那么可以使用"${file%.*}.txt",但这对于没有扩展名的文件来说是很危险的。
- 请注意,如果有人无法像我一样完成这项工作:请注意,大括号内没有$!
- 我需要一种方法来永久地收藏/书签这个答案,我永远记不清确切的语法,最后我会用谷歌搜索它。
- 是否有一种方法可以递归地执行此操作,即即使要重命名的文件不是直接位于当前工作目录中,而是位于其各种直接和间接子目录中?
- 我不知道这是怎么回事?你能解释mv命令的逻辑吗?
- 如果你谷歌"Linux重命名多个扩展名",你没有找到这个答案,你会在unix.stackexchange上找到一些不满意的答案,最后花一些时间找出正确的答案,因为你知道mv file{1,2}是如何工作的,从而得出这个答案。谷歌"Linux批量重命名"会直接把我带到这里…
- @danip括号结构中的百分号将字符从末尾去掉。括号结构中还有一个散列,它将字符从开头剥离。检查:tldp.org/ldp/abs/html/parameter substitution.html psub2
- 另一个堆栈交换答案(我找不到!)建议这样做,但也使用--运算符:mv--"$file""$file%.html.txt",该运算符防止mv将以"-"开头的文件名作为参数进行分析。
- 也适用于副本(CP)。谢谢。
要获得更好的解决方案(只有bash功能,而不是外部调用),请参阅其他答案之一。
以下操作可以并且不需要系统具有rename程序(尽管您通常会在系统上使用此程序):
1 2 3
| for file in *.html; do
mv"$file""$(basename"$file" .html).txt"
done |
编辑:正如注释中指出的,如果文件名中没有适当的引用(现在已在上面添加),则不适用于其中包含空格的文件名。当您只处理自己的文件时,您知道文件名中没有空格,这将起作用,但当您编写一些稍后可能重用的内容时,不要跳过适当的引用。
- 另一个不带basename&;和引号的选项:mv"$file""$file/%.html/.txt"(有关详细信息,请参阅man bash,参数扩展)
- 当然,只有当文件都在当前目录中时才好,因为basename去掉了路径名部分。只是"小心"!
- 如果有许多HTML文件,请使用bash的内部字符串函数而不是basename。
- +1用于basename;尽管问题指定它用于bash shell,但可移植性很好!
- 这个解决方案不好,不仅是因为它速度慢,而且因为它不适用于文件名中包含空格的文件。您应该总是在bash脚本中进行适当的引用。mv"$file""$(basename"$file.html)".txt会更好。但是,mv"$files""$files%.html.txt"还是更好的。
- 我同意波兹萨尔的观点。如果你不小心的话,这真的会让你度过糟糕的一天。只是一个警告。
- 下面的ghostdont74回答是正确的。
- 在Windows中,您只需执行ren *.a *.b
- 除了最后一个保留为.txt的文件外,所有我的文件(其中有一个空间)都消失了:(
- 至少,使用POSIX指定的$()而不是传统的反勾号语法。提高可读性,并且当您有需要反斜杠转义为在命令替换中使用后一个字符的文本的字符时,使语法不那么模棱两可。
- @查尔斯达菲,谢谢你的指点。固定的。
- @穆罕默德,谢谢!工作!(就在您认为无法在Windows中执行批处理命令时…)
1
| rename 's/\.html$/\.txt/' *.html |
做你想要的。
- 我认为你不能像你建议的那样在bash中使用一个文本regex——你使用的是哪个shell?
- 巴什,在Ubuntu(jaunty)。
- 我用的是Mac终端
- 这是Ubuntu:unixhelp.ed.ac.uk/cgi/man-cgi上Rename版本的手册页?重命名
- (正如您从手册页中看到的,它被绑定到Perl中。)
- Rename是一些系统上的命令。我有一个Perl脚本(最初来自第一本骆驼书)来完成这项工作。还有一个同名的GNU程序,它执行大致相同的工作。我的Mac没有系统提供的"重命名"命令,或者它不在我的路径上(这是一个相当全面的命令)。
- 在自制中有一个重命名公式。
- 我喜欢你的回答。但实际上我只使用rename 's/jpg/png/' *.jpg,这更容易记忆和打字。如果文件名包含JPG,可能会导致错误,所以我将在键入之前先检查它。
- 我爱你。所有的答案。
这对我在osx上从.txt到.txt的效果很好
1
| find . -name '*.txt' -exec sh -c 'mv"$0""${0%.txt}.txt_bak"' {} \; |
- 在Linux中也可以正常工作。
- 除此之外,从.txt到.txt_bak,只需连接EDOCX1(4;)
- 这对于递归重命名很好
- 伟大的!(在Ubuntu 16.04下)我的实际用例,将所有.scss重命名为.sass(就地转换后…):find . -name '*.scss' -exec sh -c 'mv"$0""${0%.scss}.sass"' {} \;。
- 这适用于+6000个文件,Rename报告的"参数列表太长"
您要使用rename:
1
| rename -S .html .txt *.html |
这完全符合您的要求—它会将所有与*.html匹配的文件的扩展名从.html更改为.txt。
注意:GregHewgill正确地指出,这不是bash内置的,而是一个单独的linux命令。如果您只需要Linux上的一些东西,这应该可以很好地工作;如果您需要更多跨平台的东西,那么看看其他的答案之一。
- 虽然这是一个很好的解决方案,但rename程序与bash无关,也不适用于所有平台。我只在Linux上看到过。
- "$rename.html.txt*.html"结果是…(eval 1)第1行,靠近""处的语法错误。
- @格雷格:啊,是的,你说得对——我一直以为那是一个巴什式建筑。不过,我认为我从未遇到过一个没有Linux系统的Linux系统;因此,如果您只需要对Linux进行重命名,那么重命名可能是最简单的方法。
- 是,重命名在Mac终端中不可用
- 正确的语法是rename -S .html .text *.html,其中-S代表--subst-all。
- 与Ubuntu 13.10 bash中的@amber错误相同。
- @mareksebera正确的mac语法。谢谢+ 1!
- BREW安装重命名
- @Greghewgill Rename可用于带有自制的Mac OS
- 我根据@mareksebera correction更新了答案以添加缺少的-s开关。
- 对于util linux的rename 2.28.2没有-s选项。但是没有它也能工作。
- 我的Ubuntu16没有包括-s来重命名。
- 未知选项:Ubuntu上的s
在Mac上…
如果没有安装重命名:brew install rename。
rename -S .html .txt *.html
对于Ubuntu用户:
1
| rename 's/\.html$/\.txt/' *.html |
- 这不是递归的,但它在Ubuntu14.04上对我有效。
下面是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可用,那么非常简单:
如果你得到了zsh: command not found: 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和#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' - {} |
- 不,不要解析ls。这个命令很荒谬:它使用一个带有ls的glob,而不是直接使用glob。这将与包含空格、引号和(由于缺少引号)glob字符的文件名中断。
- 仅供参考,您的链接文章包含一个更新的注释,说明如果打印到终端,更新的ls"正确地"shell escapes"文件"。不过,您的观点仍然是一个很好的经验法则。
试试这个
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因为它是拉里·沃尔的剧本(由罗宾·巴克修改)。最后一个可用的URL是:tips.webdesign10.com/files/rename.pl.txt
这是一次修改多个扩展的好方法:
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 |
很有魅力。