Answers:
要获得更好的解决方案(仅具有bash功能,而不是外部调用),请参阅其他答案之一。
以下将执行并且不需要系统具有该rename
程序(尽管您通常会在系统上拥有该程序):
for file in *.html; do
mv "$file" "$(basename "$file" .html).txt"
done
编辑:正如评论中指出的那样,这对于没有适当引号的文件名(在上面已添加)不起作用。当纯粹在自己的文件上工作(您知道文件名中没有空格)时,这将起作用,但是每当您编写以后可以重用的内容时,请勿跳过正确的引用。
ren *.a *.b
$()
的语法,而不要使用旧的反引号语法。改进了可读性,并且当您有一些字符需要用反斜杠转义以在用命令替换的字符内成为原义时,语法就变得不那么模棱两可了。
如果使用bash,则不需要sed,basename,rename,expr等外部命令。
for file in *.html
do
mv "$file" "${file%.html}.txt"
done
"${file%.*}.txt"
,但这对于完全没有扩展名的文件可能会很危险。
$
花括号内部没有!
--
“ operator”:mv-“ $ file”“ $ {file%.html} .txt”该运算符可防止以mv将其解析为参数的“-”。
rename 's/\.html$/\.txt/' *.html
正是您想要的。
这在OSX上对我有效,从.txt到.txt_bak
find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;
.txt
到.txt_bak
您,就必须串联_bak
;)
.scss
为.sass
(就地转换后):find . -name '*.scss' -exec sh -c 'mv "$0" "${0%.scss}.sass"' {} \;
您要使用rename
:
rename -S .html .txt *.html
这正是您想要的,它会将所有匹配的文件的扩展名从.html
更改.txt
为*.html
。
注意:Greg Hewgill正确指出这不是内置的bash;并且是单独的Linux命令。如果您只需要Linux上的某些功能,则应该可以正常工作。如果您需要更多跨平台的内容,请查看其他答案之一。
rename
程序与之无关,bash
并且并非在所有平台上都可用。我只在Linux上看到过它。
rename -S .html .text *.html
其中-S
代表--subst-all
这是重命名命令的示例:
rename -n ’s/\.htm$/\.html/’ *.htm
-n表示这是一个测试运行,实际上不会更改任何文件。它将显示一个文件列表,如果您删除了-n,这些文件将被重命名。在上述情况下,它将把当前目录中的所有文件从.htm文件扩展名转换为.html。
如果上述测试运行的输出看起来正常,则可以运行最终版本:
rename -v ’s/\.htm$/\.html/’ *.htm
-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
中间的棘手部分是用正则表达式替换Perl,如下所示:
rename -v ’s/\.htm$/\.html/’ *.htm
在其他人的网站爬网之后,我最终在数千个子目录中找到了数千个缺少.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"
但是需要修复:处理文件名中的空格
该命令mmv
似乎可以在大量文件(每秒数万个)上非常有效地完成此任务。例如,要将所有.xml
文件重命名为.html
文件,请使用以下命令:
mmv ";*.xml" "#1#2.html"
在;
将匹配的路径时,*
将匹配的文件名,并且这些称作#1
并#2
在替换名称。
对于exec
大量文件,基于或管道的答案太慢或失败。
晚会晚了一点。您可以使用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' - {}
ls
。这个命令很荒谬:它无用地使用了带有的glob ls
,而不是直接使用glob。这将破坏包含空格,引号和(由于缺少引号)glob字符的文件名。
如果您更喜欢PERL,可以使用一个简短的PERL脚本(最初由PERL的创建者Larry Wall编写),该脚本可以完全满足您的要求: tips.webdesign10.com/files/rename.pl.txt。
对于您的示例,以下方法可以解决问题:
rename.pl 's/html/txt/' *.html
一行,没有循环:
ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
例:
$ 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
您还可以在Bash中创建一个函数,将其添加到.bashrc
或其他内容中,然后在任何需要的地方使用它。
change-ext() {
for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}
用法:
change-ext css scss
函数中的代码源:https : //stackoverflow.com/a/1224786/6732111