【发布时间】:2010-11-16 12:31:54
【问题描述】:
在一个目录中,我有一堆*.html 文件。我想将它们全部重命名为*.txt
我该怎么做?我使用 bash shell。
【问题讨论】:
标签: bash rename file-rename
在一个目录中,我有一堆*.html 文件。我想将它们全部重命名为*.txt
我该怎么做?我使用 bash shell。
【问题讨论】:
标签: bash rename file-rename
如果使用 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 解析为参数。
如需更好的解决方案(仅使用 bash 功能,而不是外部调用),请参阅 one of the other answers。
以下内容可以满足并且不需要系统具有rename 程序(尽管您通常会在系统上拥有它):
for file in *.html; do
mv "$file" "$(basename "$file" .html).txt"
done
编辑: 正如 cmets 中所指出的,这不适用于包含空格且没有正确引用的文件名(现在在上面添加)。当纯粹在您自己的文件上工作时,您知道文件名中没有空格,这将起作用,但是每当您编写可能在以后重用的内容时,请不要跳过正确的引用。
【讨论】:
ren *.a *.b
$() 而不是旧的反引号语法。提高可读性,并且当您有字符需要反斜杠转义以在使用后者的命令替换中成为文字时,使语法不那么模棱两可。
rename 's/\.html$/\.txt/' *.html
完全按照你的意愿去做。
【讨论】:
rename 's/jpg/png/' *.jpg,这样更容易记住和输入。如果文件名包含jpg可能会导致错误,所以我会在输入之前先检查它。
这对我在 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 <old_extension> <new_extension> <files>
rename -S .html .txt *.html
这正是您想要的 - 它会将所有匹配 *.html 的文件的扩展名从 .html 更改为 .txt。
注意:Greg Hewgill 正确地指出这不是内置的 bash;并且是一个单独的 Linux 命令。如果您只需要 Linux 上的某些东西,这应该可以正常工作;如果您需要更多跨平台的东西,请查看其他答案之一。
【讨论】:
rename 程序与bash 无关,也并非在所有平台上都可用。我只在 Linux 上看到过。
rename -S .html .text *.html,其中-S代表--subst-all
在 Mac 上...
brew install rename
rename -S .html .txt *.html【讨论】:
对于 Ubuntu 用户:
rename 's/\.html$/\.txt/' *.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' - '{}' \;
【讨论】:
这个问题明确提到了 Bash,但如果你碰巧有可用的 ZSH,那就很简单了:
zmv '(*).*' '$1.txt'
如果你得到zsh: command not found: zmv,那么只需运行:
autoload -U zmv
然后再试一次。
感谢original article 提供有关 zmv 的提示。
【讨论】:
zmv '(*).html' '$1.txt' 使用原始问题中的特定文件扩展名。
以下是重命名命令的示例:
rename -n ’s/\.htm$/\.html/’ *.htm
-n 表示这是一个测试运行,实际上不会更改任何文件。如果您删除 -n,它将显示将重命名的文件列表。在上述情况下,它将当前目录中的所有文件从文件扩展名 .htm 转换为 .html。
如果上述测试运行的输出看起来不错,那么您可以运行最终版本:
rename -v ’s/\.htm$/\.html/’ *.htm
-v 是可选的,但最好包含它,因为它是您将拥有的由 rename 命令所做的更改的唯一记录,如下面的示例输出所示:
$ 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
【讨论】:
一行,没有循环:
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
【讨论】:
command mmv 似乎可以非常有效地处理大量文件(每秒数万个)。例如,要将所有 .xml 文件重命名为 .html 文件,请使用:
mmv ";*.xml" "#1#2.html"
; 将匹配路径,* 将匹配文件名,这些在替换名称中分别称为 #1 和 #2。
基于exec 或管道的答案要么太慢,要么在大量文件上失败。
【讨论】:
试试这个
rename .html .txt *.html
用法:
rename [find] [replace_with] [criteria]
【讨论】:
在别人的网站爬网后,我最终发现了数千个缺少 .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"
需要修复:处理文件名中的空格
【讨论】:
这是一次修改多个扩展的好方法:
for fname in *.{mp4,avi}
do
mv -v "$fname" "${fname%.???}.mkv"
done
注意:注意扩展大小必须相同(???)
【讨论】:
聚会有点晚了。你可以用 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。这个命令很荒谬:它无用地使用带有ls 的glob,而不是直接使用glob。这将与包含空格、引号和(由于缺少引号)全局字符的文件名中断。
重命名当前目录和子目录下所有文件的文件扩展名,没有任何其他包(仅使用shell脚本):
在当前目录下创建一个shell脚本rename.sh,代码如下:
#!/bin/bash
for file in $(find . -name "*$1"); do
mv "$file" "${file%$1}$2"
done
由./rename.sh .old .new 运行。
例如。 ./rename.sh .html .txt
【讨论】:
很好很简单!
find . -iname *.html -exec mv {} "$(basename {} .html).text" \;
【讨论】:
与之前的建议类似,我就是这样做的:
find . -name '*OldText*' -exec sh -c 'mv "$0" "${0/OldText/NewText}"' {} \;
我首先验证了
find . -name '*OldText*' -exec sh -c 'echo mv "$0" "${0/OldText/NewText}"' {} \;
【讨论】:
如果您更喜欢 PERL,这里有一个简短的 PERL 脚本(最初由 PERL 的创建者 Larry Wall 编写)可以完全满足您的需求: tips.webdesign10.com/files/rename.pl.txt.
对于您的示例,以下内容应该可以解决问题:
rename.pl 's/html/txt/' *.html
【讨论】:
这是我用来将 .edge 文件重命名为 .blade.php 的内容
for file in *.edge; do mv "$file" "$(basename "$file" .edge).blade.php"; done
像魅力一样工作。
【讨论】:
您还可以在 Bash 中创建一个函数,将其添加到 .bashrc 或其他内容,然后在任何您想要的地方使用它。
change-ext() {
for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}
用法:
change-ext css scss
【讨论】:
不幸的是,可移植性并非易事。你可能需要一点 expr 魔法。
for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done
一旦你对它做你想做的事情感到满意,就移除它。
编辑:basename 对于这种特殊情况可能更具可读性,尽管expr 通常更灵活。
【讨论】:
这是一个使用 AWK 的解决方案。确保文件存在于工作目录中。否则,cd到html文件所在目录,然后执行以下命令:
for i in $(ls | grep .html); do j=$(echo $i | grep -oh "^\w*." | awk '{print $1"txt"}'); mv $i $j; done
【讨论】:
我在我的 .bashrc 中编写了这段代码
alias find-ext='read -p "Path (dot for current): " p_path; read -p "Ext (unpunctured): " p_ext1; find $p_path -type f -name "*."$p_ext1'
alias rename-ext='read -p "Path (dot for current): " p_path; read -p "Ext (unpunctured): " p_ext1; read -p "Change by ext. (unpunctured): " p_ext2; echo -en "\nFound files:\n"; find $p_path -type f -name "*.$p_ext1"; find $p_path -type f -name "*.$p_ext1" -exec sh -c '\''mv "$1" "${1%.'\''$p_ext1'\''}.'\''$p_ext2'\''" '\'' _ {} \;; echo -en "\nChanged Files:\n"; find $p_path -type f -name "*.$p_ext2";'
在像“/home/
这些命令的行为如下:
~$ find-text
Path (dot for current): example-files/
Ext (unpunctured): txt
example-files/file1.txt
example-files/file2.txt
~$ rename-text
Path (dot for current): ./example-files
Ext (unpunctured): txt
Change by ext. (unpunctured): mp3
Found files:
./example-files/file1.txt
./example-files/file1.txt
Changed Files:
./example-files/file1.mp3
./example-files/file1.mp3
~$
【讨论】:
最简单的方法是使用rename.ul,它存在于大多数 Linux 发行版中
rename.ul -o -v [oldFileExtension] [newFileExtension] [搜索要应用的文件的表达式]
rename.ul -o -v .oldext .newext *.oldext
选项:
-o: 不要覆盖已有的.newext
-v: 详细
-n:试运行
【讨论】:
在 Linux 或 windows git bash 或 windows 的 wsl 中,尝试以下命令以更改当前目录或子目录甚至其子目录中每个文件的扩展名,只需一行代码
find . -depth -name "*.html" -exec sh -c 'mv "$1" "${1%.html}.txt"' _ {} \;
【讨论】: