尽管perl
的rename
工具已成为我日常工作的宝贵伴侣,但仍有一些怪癖使工作更加困难-尤其是当文件不在当前工作目录中时。
假设有很多发票,并且我们知道customer1的所有发票都已分配给一个帐户。因此,为了使以后的脚本处理更加容易,我们希望在assi_
“ assigned”之前添加前缀。
例如:
/home/user/bizz/invoices $ ls -1 t1/inv*
t1/inv_customer1_20130506.txt
t1/inv_customer1_20130823.txt
t1/inv_customer1_20130930.txt
t1/inv_customer2_20131207.txt
t1/inv_customer2_20131113.txt
现在看看会发生什么:
/home/user/bizz/invoices $ rename 's/^/assi_/' t1/inv_customer1*
Can't rename t1/inv_customer1_20130506.txt assi_t1/inv_customer1_20130506.txt: No such file or directory
(etc.)
嘿嘿 rename
已经选择了整个路径作为前缀assi_
,而不是仅选择文件。因此,难怪它无法在不存在的目录“ assi_t1”中找到inv_customer1_20130506.txt。
那么,如何rename
教导仅将正则表达式应用于文件名呢?
注意:
1.我并不总是要转到cd
子目录。
2.find
如果可能的话,我将尽量避免使用循环。
rename
之所以这样工作,是因为它可以在目录之间移动文件。像一样mv
,它作用于整个路径,而不仅仅是最后一个组件。
如果您只想修改最后一个组件,则可以将regexp锚定在(\A|?<=/)
,并确保它不匹配任何一个/
,仅匹配到last /
。
rename 's~(\A|?<=/)(?=[^/]*)\z~assi_~' t1/inv_customer1*
另一种方法是首先分割文件名。
rename 's~(.*/)~~s; my $d = $1; s/\A/assi_/; $_ = "$d$_"' t1/inv_customer1*
您也可以使用该File::Spec
模块。这具有应付非Unix路径的优势。
rename 'use File::Spec::Functions; my ($v,$d,$f) = splitpath($_); $f =~ s/\A/assi_/; $_ = catpath($v,$d,$f)' t1/inv_customer1*
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句