我正在尝试编写一个 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)工具(可能被称为rename
或prename
或 ,具体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_//' {} \;