【问题标题】:execute command line command from Perl?从 Perl 执行命令行命令?
【发布时间】:2011-05-05 09:21:41
【问题描述】:

大家好,

我需要从 Perl 文件执行这个命令行命令:

for file in *.jpg ; do mv $file `echo $file | sed 's/\(.*\.\)jpg/\1jp4/'` ; done

所以我添加了文件夹并尝试了:

system "bash -c 'for file in $mov0to/*.jp4 ; do mv $file `echo $basedir/internal/0/$file | sed 's/\(.*\.\)jp4/\1jpg/'` ; done'";

但我得到的只是:

sh: Syntax error: "(" unexpected
No file specified

我在 Kubuntu 10.4

谢谢, 一月

【问题讨论】:

  • 你是为了运行一个 for 循环并调用 sed 和 mv 吗? Perl 诸神感到被侮辱了,现在他们会惩罚你和你的孩子,直到你重写你的脚本来用 Perl 完成这一切。

标签: perl bash command-line command system


【解决方案1】:

我能想到很多更好的方法来做到这一点,但理想情况下你想要纯 Perl:

use File::Copy qw( move );
opendir DIR, $mov0to or die "Unable to open $mov0to: $!";
foreach my $file ( readdir DIR ) {
    my $out = $file;
    next unless $out =~ s/\.jp4$/.jpg/;
    move "$mov0to/$file", "$basedir/internal/0/$out" or die "Unable to move $mov0to/$file->$basedir/internal/0/$out: $!";
}
closedir DIR;

如果你坚持在 Bash 中进行提升,你应该这样做:

system qq(bash -c 'for file in $mov0to/*.jp4 ; do mv \$file $basedir/internal/0/\${file\/%.jp4\/.jpg} ; done');

【讨论】:

    【解决方案2】:

    双引号内的所有变量都将被插值,特别是您在 bash for 循环中使用的 $file。我们没有足够的上下文来知道其他变量($mov0to$basedir)来自哪里或它们包含什么,因此它们可能会遇到相同的问题。双引号也在 sed 部分吃掉你的反斜杠。

    Andy White 是对的,如果 bash 命令位于单独的脚本中,您将不会那么混乱。

    【讨论】:

      【解决方案3】:

      这很可能是嵌套引号的问题。我建议要么将该 bash 命令移动到它自己的 (bash) 脚本文件中,要么直接在 Perl 代码中编写循环/逻辑,如果需要,可以进行更简单的系统调用。

      【讨论】: