我正在测试/尝试this Perl one-liner,我正在试图弄清楚文件发生了什么。我再也看不到这些文件了。 我删除了它们或出了什么问题吗?
列出的文件名示例(原始):
IMG_0178.JPG
IMG_0182.JPG
IMG_0183.JPG
IMG_0184.JPG
IMG_0186.JPG
我想将文件扩展名更改为小写(.jpg):
perl -e'while(<*.JPG>) { s/JPG$/jpg/; rename <*.jpg>, $_ }'
答案 0 :(得分:9)
不要将rename
与glob一起使用。使用标量。尝试在替换之前将文件名分配给新变量,并将旧名称重命名为修改后的名称,如下所示:
perl -e'while(<*.JPG>) { ($new = $_) =~ s/JPG$/jpg/; rename $_, $new }'
使用ls -1
检查输出:
IMG_0178.jpg
IMG_0182.jpg
IMG_0183.jpg
IMG_0184.jpg
IMG_0186.jpg
答案 1 :(得分:4)
你的代码应该做你想做的事。
标量上下文中的<*.JPG>
之类的文件全局将返回与模式匹配的下一个文件,并且由于while
和rename
都应用了标量上下文,因此两个globs返回相同的值在每次迭代中。
while (<*.JPG>) {
s/JPG$/jpg/;
rename <*.jpg>, $_;
}
在循环的第一次迭代中,$_
将IMG_0178.JPG
设置为while
,替换将文件类型设置为小写。
然后在重命名<*.jpg>
中在标量上下文中执行并再次返回IMG_0178.JPG
- 同一列表中的第一个文件,因为Windows文件名不区分大小写。
所以最后重命名会根据需要执行rename 'IMG_0178.JPG', 'IMG_0178.jpg'
。
像这样重写rename
清楚地表明了这一点
sub ren($$) {
print "$_[0] -> $_[1]\n";
}
while (my $file = <*.JPG>) {
$file =~ s/JPG$/jpg/;
ren <*.JPG>, $file;
}
<强>输出强>
IMG_0178.JPG -> IMG_0178.jpg
IMG_0182.JPG -> IMG_0182.jpg
IMG_0183.JPG -> IMG_0183.jpg
IMG_0184.JPG -> IMG_0184.jpg
IMG_0186.JPG -> IMG_0186.jpg
所以你很幸运,你的文件应该已经根据需要重命名了。
但不这样做。特别是你应该使用print语句来代替任何关键操作运行程序,以便你可以看到将要发生的事情。
这会更好,因为id更清楚地表达了什么
perl -e '($f = $_) =~ s/JPG$/jpg/i and rename $_, $f while <*.JPG>'