Mac OS X没有有用的linux命令rename
,其格式如下:
rename 'perl-regex' list-of-files
所以这里是我放在一起,但它不重命名任何文件($新总是一样的$文件):
#!/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"; } }
这就好像我没有通过正则expression式,如果我硬编码
$new =~ s/TMP/tmp;
它会工作得很好…任何想法?
$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 $@;
你不能把整个句子s/TMP/tmp;
在一个变量。 但是,你可以做类似的事情
$new =~ s/$find/$replace;
$find
你的正则表达式和$replace
你想要替换的比赛。
如果你仍然想传递整个句子,你可能想看看eval() 。
有两种方法可以优雅地解决
需要两个独立的命令行参数:一个用于正则表达式,一个用于替换。 这是不雅和限制性的。
my ($search, $replace, @files) = @ARGV; ...; my $new = $file; $new =~ s/$search/$replace/e; # the /e evals the replacement, # allowing us to interpolate vars
像my-rename '(.*)\.txt' '@{[our $i++]}-$1.foo' *.txt
。 这允许通过字符串变量插值来执行几乎任何代码。
(1):在老版本中没有嵌套正则表达式
只要允许任意的Perl代码,类似于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
my-rename 'next FILENAME if /^\./; our $i++; s/(.*)\.txt/$i-$1.foo/; $_' *.txt
my-rename 'next FILENAME if /^\./; our $i++; s/(.*)\.txt/$i-$1.foo/; $_' *.txt
。 这将跳过以点开头的所有文件,注册一个全局变量$i
,并从每个文件名之前的一个向上计数,并更改扩展名。 然后我们在最后一个语句中返回$_
。
循环构建了原始文件和新文件名的对,可以在第二个循环中处理。
这可能是相当灵活的,而不是太低效。
那么,它已经是一个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
。