批量重命名以点结尾的文件

批量重命名以点结尾的文件

我有一个大型 unix 文件服务器,带有一个大型 SMB 共享。它为 Mac、Linux 和 Windows 客户端提供服务。此机器上的大部分文件已从 Mac Xserve 迁移到那里。备份共享的方法之一是通过 Windows 机器。如果文件名中有它不喜欢的字符,该特定备份软件就会失败。

我已设法修复了大多数文件名问题,但对以点结尾的文件仍感到困扰。例如:

  • filename.
  • newfile.txt.
  • stupid old file.

我正在尝试找到一种方法来批量重命名所有以点结尾的文件,使其不带点。因此filename.变成filename

find . -name "*."

可以找到文件。我尝试通过 sed 进行管道传输:

find . -name "*." | sed 's/.$//'

它可以在控制台中完成任务,但实际上不会重命名文件。这就是我遇到的问题。

答案1

如果您有 Perl 脚本版本rename(称为renameprename):

rename 's/\.$//' *.

或者 util-linux 版本(称为renamerename-ul):

 rename . '' *.

如果您运行不带参数的命令并得到类似以下内容:

用法:重命名 [-v] [-n] [-f] perlexpr [文件名]

那么它是 Perl 脚本版本。

就像是:

rename.ul:参数不足

用法:rename.ul [选项] 表达式替换文件...

选项:-v,--verbose 解释正在执行的操作 -V,--version
输出版本信息并退出 -h,--help 显示此帮助并退出

表示它是 util-linux 版本。

答案2

有点黑客但应该可以工作:

如果要重命名带有尾随点的文件和目录:

    find . -name "*." -print0 | xargs -0 -n 1 my_rename.sh

或者如果您只想重命名文件:

    find . -name "*." -type f -print0 | xargs -0 -n 1 my_rename.sh

脚本如下my_rename.sh

#!/bin/bash
mv "$1" "${1%%.}"

(另外不要忘记使脚本可执行: chmod +x my_rename.sh)2

答案3

这看起来应该可以完成这个工作:

find . -type f -name '*\.' -exec bash -c 'mv "$1" "${$1%.}"' _ {} \;

这将 find 限制为仅以句点结尾的文件(否则它将匹配当前工作目录“。”),然后mv "$1" "${$1%.}"对找到的每个文件名执行带引号的 shell 代码片段 ( )。在 shell 代码片段中,它使用 bash 参数扩展和替换来删除尾随的“。”。末尾的另一行 noise 是 find -exec 所必需的:{}是 find 中匹配的文本,\;是结束 exec 字符串所必需的,我相信它_告诉 exec 将 {} 作为参数 ( $1) 传递给sh命令。说实话,-exec 的这种特定用法对我来说很新奇,我发现它这里

bash 替换位非常简单,我经常使用它来重命名文件,例如FILENAME=foo.JPG; mv ${FILENAME} ${FILENAME%.JPG}.jpg从 FILENAME 中删除“.JPG”并将其替换为“.jpg”

如果您仍然想使用 sed 而不是 bash 扩展,这看起来可以完成这项工作:

find . -type f -name '*\.' -exec sh -c 'mv "{}" "$(echo {} | sed s/\.$// )"' \;

-exec我首先尝试在不调用的情况下解决这个问题sh -c,但这并不像在尝试执行 sed 时扩展 {}(或使用之前的 bash 替换示例)。

还请注意,您必须在要扩展的文件名周围加上“ ” (例如,{} 或 $1,具体取决于示例),因为您的示例文件中有空格。这仍可能中断,具体取决于文件中的特殊字符 (例如,文件名中的“ 会导致问题)。

相关内容