在 Bash 中递归更改文件扩展名

Posted

技术标签:

【中文标题】在 Bash 中递归更改文件扩展名【英文标题】:Recursively change file extensions in Bash 【发布时间】:2014-03-25 23:33:37 【问题描述】:

我想递归地遍历一个目录并将某个扩展名的所有文件的扩展名更改为.t1.t2。执行此操作的 bash 命令是什么?

【问题讨论】:

恕我直言,这不是一个重复的问题 - 另一个问题不是递归的 相关:askubuntu.com/questions/35922/… @AmalAntony :如果您没有 rename,请编写一个 shell 脚本,重命名单个文件(在您的简单情况下很简单),然后使用 find 来应用它为所有带有违规扩展名的文件编写脚本。 【参考方案1】:

用途:

find . -name "*.t1" -exec bash -c 'mv "$1" "$1%.t1".t2' - '' +

如果您有可用的rename,请使用以下一个

find . -name '*.t1' -exec rename .t1 .t2  +
find . -name "*.t1" -exec rename 's/\.t1$/.t2/' '' +

【讨论】:

find . -name '*.t1' -exec rename .t1 .t2 + (我的rename 版本不允许使用 sed 样式替换表达式。我一定很喜欢 Linux。我以前必须为 Windows 安装 TotalCommander 才能执行此类操作。) 如果有人想知道 "$1%.t1".t2 部分的作用,就像我一样:它使用 bash 字符串操作来执行以下操作: 1/ 获取第一个位置参数 $1 并截断 @987654329 @ 从其末尾开始的字符串文字(百分号 % 运算符)。 2/ 将.t2 字符串文字附加到结果中。 重命名在 OSX 中对我不起作用,但是 bash 版本很棒 b/c 我刚刚在 mv 前面添加了“git”,现在 git 很高兴:-D 首选用户 find . -type f -name '*.t1' 以避免文件夹【参考方案2】:

如果您的bash 版本支持globstar 选项(版本4 或更高版本):

shopt -s globstar
for f in **/*.t1; do
    mv "$f" "$f%.t1.t2"
done 

【讨论】:

【参考方案3】:

在全新安装的 debian 14 上,上述解决方案均不适用于我。 这应该适用于任何 Posix/MacOS

find ./ -depth -name "*.t1" -exec sh -c 'mv "$1" "$1%.t1.t2"' _  \;

所有学分: https://askubuntu.com/questions/35922/how-do-i-change-extension-of-multiple-files-recursively-from-the-command-line

【讨论】:

【参考方案4】:

我会在 bash 中这样做:

for i in $(ls *.t1); 
do
    mv "$i" "$i%.t1.t2" 
done

编辑: 我的错误:它不是递归的,这是我递归更改文件名的方法:

for i in $(find `pwd` -name "*.t1"); 
do 
    mv "$i" "$i%.t1.t2"
done

【讨论】:

Don't parse ls,并查看同一页面,了解为什么您的 find 语法不好。另外,请确保您quote your variables【参考方案5】:

或者您可以简单地安装mmv 命令并执行以下操作:

mmv '*.t1' '#1.t2'

这里的#1 是第一个全局部分,即*.t1 中的*

或者在纯 bash 的东西中,一个简单的方法是:

for f in *.t1; do
    mv "$f" "$f%.t1.t2"
done

(即:for 可以在没有外部命令帮助的情况下列出文件,例如 lsfind

HTH

【讨论】:

我假设 OP 对“递归”的使用也是指重命名目录子目录中的文件。 这是第一个 glob 部分,即*.t1 中的*【参考方案6】:

我对这些解决方案之一的懒惰复制粘贴不起作用,但我已经安装了fd-find,所以我使用了它:

fd --extension t1 --exec mv  ..t2

来自fd 的联机帮助页,执行命令时(使用--exec):

          The following placeholders are substituted by a
          path derived from the current search result:

               path
          /    basename
          //   parent directory
          .    path without file extension
          /.   basename without file extension

【讨论】:

以上是关于在 Bash 中递归更改文件扩展名的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Bash 的“查找”更改类型文件的扩展名? [复制]

递归查找具有特定扩展名的文件

Bash 重命名扩展递归

什么递归扩展到当前目录中的所有文件?

错误 - 在Windows 7中使用“Git Bash Here”时,“文件扩展名.vbs没有脚本引擎”

将文件重命名为 md5 sum + 扩展名 (BASH)