如何使用 bash 脚本重命名当前目录及其子目录中的文件?

Posted

技术标签:

【中文标题】如何使用 bash 脚本重命名当前目录及其子目录中的文件?【英文标题】:How to rename files in current directory and its subdirectories using bash script? 【发布时间】:2012-05-19 14:15:57 【问题描述】:

我可以使用“重命名”命令将缺少的字符添加到当前目录中的所有文件名,如下所示:

echo "Renaming files..."
rename -v "s/^abcd124(.+)/abcd1234$1/" *.wav.gz;
echo "Done."

但是,我想对当前目录它的所有子目录执行此操作。我试过这个:

echo "Renaming files..."
for dir in $(find ./ -type d); do
    rename -v "s/^$dir\/abcd124(.+)/$dir\/abcd1234$1/" *.wav.gz;
done;
echo "Done."

但是,如果 $dir 变量包含以下任何特殊字符:[]()^$.|*+?\,则它们无法使用 \ 正确转义,我的脚本将失败。

解决此问题的最佳方法是什么?另外,你们觉得用awk来解决这个问题怎么样(优点/缺点?)

【问题讨论】:

【参考方案1】:

你也可以试试:

find . -name "*.wav.gz" | xargs rename -v "s/abcd124*/abcd1234$1/"

它适用于具有“xargs”命令的较新的 Unix 系统。请注意,我稍微编辑了正则表达式。

【讨论】:

对于包含空格的文件名将失败。 这是真的。尽管我现在需要重命名的所有文件的文件名中都没有空格,但我将来使用的文件可能会。如何使脚本占文件名中的空格?【参考方案2】:

试试:

find ./ -type d -execdir rename -v "s/^abcd124(.+)/abcd1234\1/" *.wav.gz ";"

Find 确实已经为您的文件提供了一个迭代器 - 您不需要在它周围使用 for 或在后面使用 xargs ,这些都是常见的。好吧 - 在极少数情况下,它们可能会有所帮助,但通常不会。

在这里,-execdir 很有用。 Gnu-find 有它;我不知道你的发现是否也有。

但是您需要确保在您启动此命令的目录中没有 *.wav.gz 文件,因为否则您的 shell 会扩展它,并将扩展的名称交给重命名。

注意:我从重命名中收到警告,我应该在正则表达式中将 \1 替换为 $1,但如果这样做,则不会捕获该模式。我必须使用 \1 才能使其工作。

这是另一种方法。如果我们搜索 wav.gz 文件,为什么还要搜索目录?

find . -name "*.wav.gz" -exec rename -v "s/^abcd124(.+)/abcd1234\1/"  ";"

【讨论】:

没用! :( 我运行了它,它没有重命名任何东西。我尝试删除“* .wav.gz”周围的引号,在这种情况下,它将一个文件重命名为 abcd1234(不识别 $1),然后无法重命名其他的,因为它们与 abcd1234 冲突。不过,感谢您的建议,我学到了很多东西。还有其他想法吗? @jessica:你是对的。我更改了代码和解释,请参阅最后 2 段。 这也不起作用——它给了我起始目录中每个文件的警告,不重命名它们,也不查看它的子目录。此外,出于我的目的,脚本需要从起始目录中运行,并且不能为每个文件打印出警告。它必须是防弹的! 好吧,我测试了它,它对我有用。现在我做了第二种方法(最后两行),我也进行了测试。它也有效,也给了我警告,但如果我认真对待警告,它就不起作用。当然,您可以通过附加2>/dev/null 来消除警告。或者你打开 rename 所在的 perl 脚本,并在那里隐藏/更正它。或提交错误报告以重命名。或者重写你需要的 rename 部分,但我不会。我会忍受这些警告。程序是否防弹不取决于警告消息,我可以向你断言,但我也会持怀疑态度。 你给我的最后一个脚本对我也不起作用 - 它警告所有要重命名的文件(包括文件名中带有空格的文件),但没有重命名它们! 【参考方案3】:

bash 4:

shopt -s globstar
rename -v "s/^$dir\/abcd124(.+)/$dir\/abcd1234$1/" **/*.wav.gz;

【讨论】:

【参考方案4】:

请注意,Gentoo Linux 的重命名实用程序指向

http://developer.berlios.de/project/showfiles.php?group_id=413

通过它的 ebuild

http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sys-apps/rename/rename-1.3.ebuild?view=markup

对于 Debian 或 Ubuntu,

rename/usr/bin/prename,这是一个 perl 脚本

请在搬家前查看rename --help

【讨论】:

以上是关于如何使用 bash 脚本重命名当前目录及其子目录中的文件?的主要内容,如果未能解决你的问题,请参考以下文章

在 bash 脚本中获取祖父目录 - 为路径中的目录重命名文件

根据 Bash 中的模式重命名目录

使用 bash 脚本批量重命名 FTP 服务器上的文件

for in循环语句批量重命名的问题;bash

macos 中目录重命名的意外行为(其他 posix 风格?)

ubuntu /bash 下递归重命名文件和目录