Mac Os X没有有用的linux命令rename
,它具有以下格式:
rename 'perl-regex' list-of-files
所以这就是我放在一起但它没有重命名任何文件($ new总是与$ file相同):
#!/usr/bin/env perl -w
use strict;
use File::Copy 'move';
my $regex=shift;
my @files=@ARGV;
for my $file (@files)
{
my $new=$file;
$new =~ "$regex"; # this is were the problem is !!!
if ($new ne $file)
{
print STDOUT "$file --> $new \n";
move $file, ${new} or warn "Could not rename $file to $new";
}
}
就好像我没有通过正则表达式,如果我将其硬编码为
$new =~ s/TMP/tmp;
它会工作得很好...... 有什么想法吗?
答案 0 :(得分:3)
$operator = 's/TMP/tmp/';
print $operator;
并没有神奇地评估操作员,所以
应该不足为奇$operator = 's/TMP/tmp/';
$x =~ $operator;
也没有。如果要评估Perl代码,则必须将其传递给Perl解释器。您可以使用eval EXPR
访问它。
$operator = 's/TMP/tmp/';
eval('$x =~ '.$operator.'; 1')
or die $@;
答案 1 :(得分:2)
您不能将整个句子s/TMP/tmp;
放在变量中。但是,您可以执行类似
$new =~ s/$find/$replace;
$find
是你的正则表达式,$replace
你要用什么代替匹配。
如果您仍想传递整个句子,可能需要查看eval()。
答案 2 :(得分:2)
有两种方法可以优雅地解决这个问题
需要两个单独的命令行参数:一个用于正则表达式,另一个用于替换。这是不优雅和限制性的。
my ($search, $replace, @files) = @ARGV;
...;
my $new = $file;
$new =~ s/$search/$replace/e; # the /e evals the replacement,
# allowing us to interpolate vars
像[{1}}一样调用。这允许通过字符串变量插值执行几乎任何代码。
(1):旧的perls中没有嵌套的正则表达式
只允许任意Perl代码,类似于my-rename '(.*)\.txt' '@{[our $i++]}-$1.foo' *.txt
。 perl -ne'...'
开关的语义是当前行作为-n
传递。将文件名作为$_
传递是有意义的,并使用最后一个语句的值作为新文件名。这会导致像
$_
这可以像# somewhat tested
my ($eval_content, @files) = @ARGV;
my $code = eval q' sub {
no strict; # could be helpful ;-)
my @_out_;
FILENAME:
for (@_) {
my $_orig_ = $_;
push @_out_, [ $_orig_ => do { ' . $eval_content . q' } ];
# or
# do { " . $eval_content . " };
# push @_out_, [ $_orig_, $_ ];
# if you want to use $_ as out-argument (like -p).
# Can lead to more concise code.
}
return @_out_;
} ';
die "Eval error: $@" if $@;
for my $rename ($code->(@files)) {
my ($from, $to) = @$rename;
...
}
一样调用。跳过以点开头的所有文件,注册一个全局变量my-rename 'next FILENAME if /^\./; our $i++; s/(.*)\.txt/$i-$1.foo/; $_' *.txt
,并在每个文件名前面放一个向上计数的数字,并更改扩展名。然后我们在最后一个语句中返回$i
。
循环构建原始文件名和新文件名的对,可以在第二个循环中处理。
这可能非常灵活,而且效率不高。
答案 3 :(得分:2)
嗯,它已经是一个Perl实用程序了,它在CPAN上:http://cpan.me/rename。您可以直接使用该实用程序附带的模块File::Rename:
#!/usr/bin/env perl
use File::Rename qw(rename);
rename @ARGV, sub { s/TMP/tmp/ }, 'verbose';
其他可能性是从该分发中连接模块和脚本,并将生成的文件放在$PATH
的某个位置。