我找到了如何使用rename
命令从终端重命名
但是,我找不到如何从特定值重命名?假设我想从title223
开始重命名(不一定是title001
)。
这是什么语法?
谢谢。
答案 0 :(得分:0)
我希望我找到你的问题。
如果要使用此命令重命名多个文件,还要使用一些 Perl 功能,代码等;你明确地声明了它。因此这个命令不正确:
~ ❱ rename -n -v 's/_/printf("%.2d",$n++)/e' *.txt
Global symbol "$n" requires explicit package name (did you forget to declare "my $n"?) at (user-supplied code).
但这个是正确的:
~ ❱ rename -n -v 'my $n;s/_/printf("%.2d",$n++)/e' *.txt
00rename(0_file.txt, 01file.txt)
00rename(1_file.txt, 11file.txt)
00rename(2_file.txt, 21file.txt)
00rename(3_file.txt, 31file.txt)
00rename(4_file.txt, 41file.txt)
但是这段代码的问题在于printf
函数没有将其结果放在替换中,为了解决这个问题,我们可以使用sprintf
。
将零前导和_
置于开头
~ ❱ rename -v -n 'my $n;s/^/sprintf("%.3d_",$n++)/ge' *.txt
rename(0_file.txt, 000_0_file.txt)
rename(1_file.txt, 000_1_file.txt)
rename(2_file.txt, 000_2_file.txt)
rename(3_file.txt, 000_3_file.txt)
rename(4_file.txt, 000_4_file.txt)
如您所见000_
为零,因为$n
是本地的,并且每行都声明它。
因此,我们可以通过以下方式制作全球:our
关键字:
~ ❱ rename -v -n 'our $n; s/^/sprintf("%.3d_",$n++)/ge' *.txt
rename(0_file.txt, 000_0_file.txt)
rename(1_file.txt, 001_1_file.txt)
rename(2_file.txt, 002_2_file.txt)
rename(3_file.txt, 003_3_file.txt)
rename(4_file.txt, 004_4_file.txt)
最终你的要求:我想从title223重命名
我不肯定,但我认为你不能以这种方式使用rename
命令,它应该可以工作但是...... !!!
在这种情况下,我更喜欢使用 Perl one-liner
~ ❱ perl -le '($old=$_) && s/^/sprintf("%.3d_",$n++)/e && print "$old => $_" for <*.txt>'
0_file.txt => 000_0_file.txt
1_file.txt => 001_1_file.txt
2_file.txt => 002_2_file.txt
3_file.txt => 003_3_file.txt
4_file.txt => 004_4_file.txt
开始时形成一个特殊值,如223
:
~ ❱ perl -le '$n=223; ($old=$_) && s/^/sprintf("%.3d_",$n++)/e && print "$old => $_" for <*.txt>'
0_file.txt => 223_0_file.txt
1_file.txt => 224_1_file.txt
2_file.txt => 225_2_file.txt
3_file.txt => 226_3_file.txt
4_file.txt => 227_4_file.txt
而不是print "$old => $_
使用rename $old,$_
功能。
对于这个,您必须使用find
命令
~ ❱ find . -name '*.txt'
./4_file.txt
./2_file.txt
./0_file.txt
./3_file.txt
./1_file.txt
~ ❱ find . -name '*.txt' > find.log
~ ❱
~ ❱ # run perl with print just for test
~ ❱
~ ❱ perl -lne '$n=223; ($old=$_) && s/(?<=\.\/)(?=)/sprintf("%.3d_",$n++)/e && print "$old => $_"' find.log
./4_file.txt => ./223_4_file.txt
./2_file.txt => ./223_2_file.txt
./0_file.txt => ./223_0_file.txt
./3_file.txt => ./223_3_file.txt
./1_file.txt => ./223_1_file.txt
~ ❱
~ ❱ # Ohhhhh Nooooo it is still 233!
~ ❱
~ ❱ # first solution: using BEGIN{ $n=233 }
~ ❱
~ ❱ perl -lne 'BEGIN{$n=223}; ($old=$_) && s/(?<=\.\/)(?=)/sprintf("%.3d_",$n++)/e && print "$old => $_"' find.log
./4_file.txt => ./223_4_file.txt
./2_file.txt => ./224_2_file.txt
./0_file.txt => ./225_0_file.txt
./3_file.txt => ./226_3_file.txt
./1_file.txt => ./227_1_file.txt
~ ❱
~ ❱ # second solution is: using static declaration
~ ❱ # in Perl it is: state
~ ❱ # thus we should use: state $n=223;
~ ❱ # but we have to turn on Perl 5 feature with -E
~ ❱
~ ❱ perl -lnE 'state $n=233; ($old=$_) && s/(?<=\.\/)(?=)/sprintf("%.3d_",$n++)/e && print "$old => $_"' find.log
./4_file.txt => ./233_4_file.txt
./2_file.txt => ./234_2_file.txt
./0_file.txt => ./235_0_file.txt
./3_file.txt => ./236_3_file.txt
./1_file.txt => ./237_1_file.txt
~ ❱
~ ❱ # test it with rename $old,$_
~ ❱ perl -lnE 'state $n=233; ($old=$_) && s/(?<=\.\/)(?=)/sprintf("%.3d_",$n++)/e && rename $old,$_' find.log
~ ❱
~ ❱ # see the result:
~ ❱
~ ❱ ls *.txt | cat -n
1 233_4_file.txt
2 234_2_file.txt
3 235_0_file.txt
4 236_3_file.txt
5 237_1_file.txt
注意 BEGIN{}
和state
不适用于rename
命令。为什么?我不知道:))