【问题标题】:Rename files in directory using a script使用脚本重命名目录中的文件
【发布时间】:2013-06-04 11:53:08
【问题描述】:

我们的 SVN 用户正在上传带有特定标签名称的文件,例如,

filename_INT filename2_INT filename3_INT

我需要我的脚本通过将 _INT 删除为其原始文件名来重命名这些文件,例如

filename filename2 filename3

在 bash 中执行此操作的最佳方法是什么?

我尝试使用 sed 但它在脚本上失败但在命令行上却失败了,

[root@hostname tags]# echo filename_INT | sed 's/_INT[a-z.]*//g'

文件名.php

【问题讨论】:

  • 你想在 SVN 中重命名这些文件,还是只在本地重命名?

标签: bash


【解决方案1】:

这个单行应该处理当前目录下的所有*_INT文件:

for file in *_INT; do mv "$file" "${file%_INT}"; done

如果你想对所有文件和子目录递归,你可以这样做:

find path -name '*_INT' | sed -e 's/\(.*\)_INT$/mv "&" "\1"/'

这个输出是一堆mv 打印但未执行的命令。如果它看起来不错并且您想执行它,只需将其通过管道传输到 sh,如下所示:

find path -name '*_INT' | sed -e 's/\(.*\)_INT$/mv "&" "\1"/' | sh

【讨论】:

  • 我认为这是一个错字,$file 而不是 $i
【解决方案2】:

这需要在您的 Subversion 存储库中完成,还是仅在本地完成?

如果只是在本地,您可以使用find 查找您的所有文件:

find . -name "*_INT"

文件名称中是否包含空格?如果没有,以下应该可以工作:

find . -name "*_INT" | while read file
do
    mv $file ${file%_INT}
done

${file%_INT} 使用称为Pattern Matching Operators 的 bash/kornshell 机制。这些可以快速过滤掉文件名中的前缀和后缀。例如,如果:

$ file=foo.txt_INT
$ echo $file         #Prints "foo.txt_INT"
$ echo ${file%_INT}  #Prints "foo.txt"
$ echo ${file#foo}   #Prints ".txt_INT"

现在您有了文件的旧名称和新名称,您可以简单地使用mv 命令。当然,可能已经存在具有该名称的文件。可以被覆盖吗?如果没有,您将不得不弄清楚如何处理它:

find . -name "*_INT" | while read file
do
    if [ ! -e $file ]
    then
        mv $file ${file%_INT}
    else
        echo "File ${file%_INT} already exists"
    fi
done

【讨论】:

    【解决方案3】:

    如果您有权访问rename 命令:

    rename 's/_INT//' *_INT
    

    【讨论】:

    • 谢谢大家。我在使用 janos 脚本时遇到了一些困难,但最终还是解决了。
    【解决方案4】:

    rename 命令应该是您最好的选择。我的手册页告诉我(我已验证)这可行:

    rename _INT "" *_INT
    

    【讨论】: