我想重命名所有与模式匹配的文件。 这种衬板通常对我有用,但是我遇到了一些错误。
我拥有的文件名种类:PMSNpoda5718_1p2g_out_fst.txt SCSNpoda5718_1p2g_out_fst.txt
我想要的文件名:PM-SN_poda5718_1p2g_out_fst.txt SC-SN_poda5718_1p2g_out_fst.txt
我的第一次尝试是:
ls *fst.txt | perl -ne '/^([A-Z][A-Z])([A-Z][A-Z])(poda.*?$)/; system("mv $_ $1-$2_$3")'
但这没用。
最后,我想出了一行可以准确打印出我想要的东西
ls *fst.txt | perl -lne '/([a-zA-Z]{2})([a-zA-Z]{2})(poda.*?$)/; print "mv $_ $1-$2_$3"'
打印:
mv PMSNpoda5718_1p2g_out_fst.txt PM-SN_poda5718_1p2g_out_fst.txt
mv SCSNpoda5718_1p2g_out_fst.txt SC-SN_poda5718_1p2g_out_fst.txt
但是当我使用它来重命名文件时:
ls *fst.txt | perl -lne '/([a-zA-Z]{2})([a-zA-Z]{2})(poda.*?$)/; system("mv $_ $1-$2_$3")'
我明白了
sh: $'32mPMSNpoda5718_1p2g_out_fst.txt\E[0m': command not found
mv: missing destination file operand after ''$'\033''[01'
Try 'mv --help' for more information.
sh: $'32mSCSNpoda5718_1p2g_out_fst.txt\E[0m': command not found
mv: missing destination file operand after ''$'\033''[01'
Try 'mv --help' for more information.
再次添加回声
ls *fst.txt | perl -lne '/([a-zA-Z]{2})([a-zA-Z]{2})(poda.*?$)/; system("echo mv $_ $1-$2_$3")'
我明白了
mv
h: $'32mPMSNpoda5718_1p2g_out_fst.txt\E[0m': command not found
mv
h: $'32mSCSNpoda5718_1p2g_out_fst.txt\E[0m': command not found
有人可以指出这是什么错误,以便我了解我在做什么错吗?
谢谢!
答案 0 :(得分:4)
没有理由通过外壳程序运行重命名。
ls -1 *fst.txt | perl -MFile::Copy=move -wlnE'
$new = s/([a-zA-Z]{2})([a-zA-Z]{2})/$1-$2_/r; move $_, $new'
请注意-1
上的ls
选项,以便每行确实获得一个文件名。
32m
和[0m
是ANSI转义符,可以为终端设置颜色(和其他属性),通常用于外壳配置(例如提示)。也许您的ls
正在将它们推出,而mv
正在将它们与之混淆?另一个例子说明为什么最好避免通过外壳,除非有必要。
在某些Shell中,现有的别名实际上是通过各种选项运行命令(这就是ls
输出被这些代码“修饰”的原因),可以通过在命令前加上反斜杠来消除该别名, \ls
。
另一种选择是尽可能减少对系统的依赖,并在程序中建立文件列表。
perl -MFile::Copy=move -wE'
for (glob "*fst.txt") {
$new = s/([a-zA-Z]{2})([a-zA-Z]{2})/$1-$2_/r;
move $_, $new or warn "Cant rename $_ to $new: $!" }'
glob
上现在负责建立正确的文件列表。