533

在一个目录中,我有一堆*.html文件。我想将它们全部重命名为*.txt

我怎样才能做到这一点?我使用 bash shell。

4

28 回答 28

738

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

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done
于 2009-08-04T00:17:20.137 回答
412

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


以下将做并且不需要系统具有该rename程序(尽管您通常会在系统上拥有它):

for file in *.html; do
    mv "$file" "$(basename "$file" .html).txt"
done

编辑:正如评论中所指出的,这不适用于没有正确引用的文件名中包含空格的文件名(现在在上面添加)。当纯粹在您自己的文件上工作时,您知道文件名中没有空格,这将起作用,但是每当您编写可能在以后重用的内容时,请不要跳过正确的引用。

于 2009-08-03T21:46:11.330 回答
199
rename 's/\.html$/\.txt/' *.html

做你想要的。

于 2009-08-03T21:45:35.840 回答
141

这在 OSX 上对我有用,从 .txt 到 .txt_bak

find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;
于 2014-12-04T03:12:20.363 回答
98

你想使用rename

rename -S <old_extension> <new_extension> <files>

rename -S .html .txt *.html

这正是您想要的 - 它会将所有匹配的文件的扩展名从.html更改为。.txt*.html

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

于 2009-08-03T21:44:13.893 回答
36

在 Mac 上...

  1. 如果您还没有安装重命名:brew install rename
  2. rename -S .html .txt *.html
于 2015-07-22T22:28:02.703 回答
16

对于 Ubuntu 用户:

rename 's/\.html$/\.txt/' *.html
于 2015-02-27T08:00:40.647 回答
15

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

于 2018-09-21T13:46:42.693 回答
10

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

zmv '(*).*' '$1.txt'

如果你得到zsh: command not found: zmv然后简单地运行:

autoload -U zmv

然后再试一次。

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

于 2017-06-20T02:45:07.983 回答
8

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

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
于 2014-09-28T05:19:46.953 回答
6

一行,没有循环:

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
于 2019-05-13T20:55:00.720 回答
5

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

mmv ";*.xml" "#1#2.html"

;匹配路径,将匹配文件名,这些在替换名称*中称为#1和。#2

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

于 2017-11-03T14:00:21.673 回答
4

试试这个

rename .html .txt *.html 

用法:

rename [find] [replace_with] [criteria]
于 2014-02-06T11:32:47.483 回答
4

在其他人的网站爬网后,我最终发现了数千个缺少 .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"

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

于 2014-07-03T11:51:12.893 回答
4

这是一次修改多个扩展的好方法:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

注意:注意扩展大小相同(???)

于 2018-09-22T20:38:29.003 回答
3

派对有点晚了。你可以用 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' - {}
于 2015-06-17T10:09:07.660 回答
3

重命名当前目录和子目录下所有文件的文件扩展名,没有任何其他包(仅使用shell脚本):

  1. rename.sh在当前目录下创建一个shell脚本,代码如下:

    #!/bin/bash
    
    for file in $(find . -name "*$1"); do
      mv "$file" "${file%$1}$2"
    done
    
  2. 运行它./rename.sh .old .new

    例如。./rename.sh .html .txt

于 2019-12-03T23:23:46.473 回答
2

如果您更喜欢 PERL,这里有一个简短的 PERL 脚本(最初由 PERL 的创建者 Larry Wall 编写)可以完全满足您的需求: tips.webdesign10.com/files/rename.pl.txt

对于您的示例,以下内容应该可以解决问题:

rename.pl 's/html/txt/' *.html
于 2013-06-28T12:13:57.550 回答
2

好又简单!

find . -iname *.html  -exec mv {} "$(basename {} .html).text"  \;
于 2019-04-30T20:56:31.553 回答
2

与之前的建议类似,我是这样做的:

find . -name '*OldText*' -exec sh -c 'mv "$0" "${0/OldText/NewText}"' {} \;

我首先验证了

find . -name '*OldText*' -exec sh -c 'echo mv "$0" "${0/OldText/NewText}"' {} \;
于 2019-12-06T08:41:14.097 回答
1

这是我用来重命名.edge文件的内容.blade.php

for file in *.edge; do     mv "$file" "$(basename "$file" .edge).blade.php"; done

像魅力一样工作。

于 2018-02-07T08:23:26.703 回答
1

您还可以在 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

于 2019-08-15T09:43:08.433 回答
0

不幸的是,可移植并非易事。你可能需要一点 expr 魔法。

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

一旦你对它做你想做的事感到高兴,就消除它。

编辑: basename对于这种特殊情况可能更具可读性,尽管expr通常更灵活。

于 2009-08-03T21:45:35.343 回答
0

这是一个使用 AWK 的解决方案。确保文件存在于工作目录中。否则,cd到 html 文件所在的目录,然后执行以下命令:

for i in $(ls | grep .html); do j=$(echo $i | grep -oh "^\w*." | awk '{print $1"txt"}'); mv $i $j; done
于 2020-07-28T12:12:11.873 回答
0

我在我的 .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/<user>/example-files”这样具有这种结构的文件夹中:

  • /home/<用户>/示例文件:
    • 文件1.txt
    • 文件2.txt
    • 文件3.pdf
    • 文件 4.csv

这些命令的行为如下:

~$ 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
~$
于 2021-01-21T21:44:27.317 回答
0

您可以使用专为批量重命名文件而设计的工具,例如renamer

重命名当前文件夹中的所有文件扩展名:

$ renamer --find ".html" --replace ".txt" --dry-run * 

这里有更多使用示例。

于 2021-05-01T12:57:54.640 回答
0

最简单的方法是使用rename.ul 它存在于大多数 Linux 发行版中

rename.ul -o -v [oldFileExtension] [newFileExtension] [搜索要应用的文件的表达式]

rename.ul -o -v .oldext .newext *.oldext

选项:

-o:不覆盖预先存在的 .newext

-v:详细

-n:试运行

于 2021-07-10T05:44:35.610 回答
0

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

find . -depth -name "*.html" -exec sh -c 'mv "$1" "${1%.html}.txt"' _ {} \;
于 2021-09-01T05:57:24.797 回答