用于删除文件名中特定字符串的脚本

用于删除文件名中特定字符串的脚本

我正在尝试编写一个 bash 脚本来删除 CentOS 上的部分文件名。我的文件名是:

119903_Relinked_new_3075_FileNote_07_02_2009_JHughes_loaMeetingAndSupport_FN_205.doc
119904_relinked_new_2206_Support_Intensity_Scale_SYCH_SIS_264549.pdf
119905_relinked_new_3075_Consent_07_06_2009_DSweet_CRFA_CF_16532.docx
29908_relinked_new_2206_Assessor_Summary_Report_SERT_I_OTH_264551.pdf
009712_relinked_new_3075_Consent_07_06_2009_CWell_DPRT_check_CF_16535.pdf

我想119903_Relinked_new_从文件名中删除。最终结果应该是:

3075_FileNote_07_02_2009_JHughes_loaMeetingAndSupport_FN_205.doc
2206_Support_Intensity_Scale_SYCH_SIS_264549.pdf
3075_Consent_07_06_2009_DSweet_CRFA_CF_16532.docx
2206_Assessor_Summary_Report_SERT_I_OTH_264551.pdf
3075_Consent_07_06_2009_CWell_DPRT_check_CF_16535.pdf

我一直在尝试多个脚本,但效果不佳。在大多数情况下,前面的数字_Relinked_new_是不同的,并且文件扩展名在.pdf.docx等之间有所不同.doc。任何帮助将不胜感激。

答案1

使用名字(1)工具(可能被称为renameprename或 ,具体perl-rename取决于您的系统):

rename 's/[0-9]+_[rR]elinked_new_//' /path/to/dir/*

这将使用正则表达式来匹配模式并将其替换为指定文件上的任何内容。

答案2

如果没有该rename工具,请使用带有参数替换的简单 shell 循环一次重命名一个文件:

for name in /path/to/dir/*_[rR]elinked_new_*
do
    newname=${name##*/}
    newname=${name%/*}/${newname#*_[rR]elinked_new_}

    # or:
    # newname=$(basename "$name")
    # newname=$(dirname "$name")/${newname#*_[rR]elinked_new_}

    mv -- "$name" "$newname"
done

在循环内部,首先将 的值newname计算为name变量的文件名部分(路径名中最后一个斜杠之后的最后一位)。

然后通过用目录路径假装变量以及从文件名开头newname删除与 shell 模式匹配的任何文本的结果来修改该变量。*_[rR]elinked_new_

通过首先将当前目录更改为文件所在的目录,可以稍微简化代码:

cd /path/to/dir || exit

for name in *_[rR]elinked_new_*
do
    newname=${name#*_[rR]elinked_new_}
    mv -- "$name" "$newname"
done

答案3

这实际上只是针对“参数列表太长”问题的评论,但它在评论框中开始看起来很混乱,所以现在它是一个答案。 :)

您收到该错误的原因是*尝试将目录中的每个文件都放到命令行上,而命令行有长度限制。相反,您可以循环遍历文件(或使用find来做类似的事情)并分别对每个文件调用重命名:

find /path/to/dir -iname '*relinked_new_*' -exec prename 's/[0-9]+_[rR]elinked_new_//' {} \;

相关内容