我有一个大的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 (称为rename或prename rename ):
rename 's/\.$//' *.
或util-linux版本(称为rename或rename-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,取决于示例),因为示例文件中有空格。 这可能仍然会根据文件中的特殊字符(例如,在文件名中会导致问题)而中断。