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

我有一个大的Unix文件服务器,与一个大的SMB共享。 它适用于Mac,Linux和Windows客户端。 这个盒子上的很大一部分文件已经从Mac Xserve迁移过来了。 共享备份的方式之一是通过Windows盒子。 如果文件名中包含不喜欢的字符,则该特定的备份软件将会失败。

我已经设法解决大部分的文件名问题,但我正在努力争取以点结束的文件。 例如:

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

我正在尝试find一些方法来批量重命名所有以点结尾的文件,并且没有点。 所以filename. 成为filename

 find . -name "*." 

寻找文件。 我已经尝试通过sedpipe道:

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

它在控制台中执行作业,但实际上并没有重命名文件。 这是我正在努力的部分。

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

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

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

  rename . '' *. 

如果你运行没有参数的命令,并得到类似的东西:

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

那么这是Perl脚本版本。

就像是:

rename.ul:没有足够的参数

用法:rename.ul [options]expressionreplace文件…

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

意味着它是util-linux版本。

有点哈克,但应该工作:

如果你想用尾随点重命名这两个文件和目录:

  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

这看起来应该做这个工作:

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

这将查找限制为仅在最后有句号的文件(否则它与当前工作目录“。”匹配),然后对每个文件执行引用的shell代码片段( mv "$1" "${$1%.}" )它find的文件名。 在shell代码段中,它使用bash参数扩展和replace来删除尾部的“。”。 最后的其他行噪声是查找所需的-exec: {}是查找匹配的文本, \; 是需要结束execstring,我相信_告诉exec作为参数( $1 )传递给sh命令。 说实话,这个-exec的具体用法对我来说是新的,我在这里find了 。

bashreplace位非常直接,我经常用这个来重命名文件,例如FILENAME=foo.JPG; mv ${FILENAME} ${FILENAME%.JPG}.jpg FILENAME=foo.JPG; mv ${FILENAME} ${FILENAME%.JPG}.jpg将从FILENAME=foo.JPG; mv ${FILENAME} ${FILENAME%.JPG}.jpg删除'.JPG',并用'.jpg'replace它。

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

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

我首先试图解决这个问题,而不会导致-exec调用sh -c ,但是在尝试执行sed(或者使用前面的bashreplace示例)时,不希望扩展{}。

另外请注意,您必须在扩展的文件名周围放置“”(例如,{}或$ 1,取决于示例),因为示例文件中有空格。 这可能仍然会根据文件中的特殊字符(例如,在文件名中会导致问题)而中断。