perl + awk +从perl中的system命令运行awk(语法问题?)

时间:2010-07-20 14:56:25

标签: perl

我写下面的脚本

  #!/usr/bin/perl

  system("  awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" /var/tmp/file " );

当我运行脚本时,我得到了:

      Can't modify string in scalar assignment at ./stam2 line 5,             near "" /var/tmp/file " )"
       Execution of ./stam2 aborted due to compilation errors.

这里有什么问题?

利迪娅

•脚本的目标是在行

中的每个参数之后操作和添加数字

4 个答案:

答案 0 :(得分:1)

你正在执行一个带有等号的语句,作为system()调用的一部分,你不能这样做。

我怀疑这可能是你想要的:

 #!/usr/bin/perl

  system( qq{  awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" /var/tmp/file } );

答案 1 :(得分:1)

Perl附带了一个名为a2p的程序,它将awk转换为Perl。您可能会发现这比从Perl调用awk更好。

答案 2 :(得分:0)

根据我对系统命令的理解,它需要一个字符串列表,其中每个字符串都是您正在运行的单个命令。您已经遇到问题,因为您的运算符未被引号括起来。我会试试这个:

system("awk -F\"=\" '{s[$1]++}{print $1s[$1],$2}' OFS=\"=\" /var/tmp/file");

然而,看起来你真正想做的事情很容易用perl的分割和连接来完成。有点像:

open my $fh, '<', "/var/tmp/file" or die "could not open for read.";
open my $output, '>', "/var/tmp/outfile" or die "could not open for write.";
while(<$fh>){
    my $line = $_;
    my @fields = split(/\=/, $line);
    for my $field (@fields){
        $field++;
    }
    print $output join(";", @fields);
}

当然可能有更优雅的方式,例如内联编辑,但这是为了给你一个想法。 更新了三个参数open

答案 3 :(得分:0)

您没有逃避或引用您的报价。

文字字符串" awk -F"以双引号开头,最后只有它才会看到另一个未转义的双引号。所以它是在F"完成的。如果您在此之后添加=,则它完全是另一个令牌。你正在分配。

错误消息说出的内容是从右到左分配的原因。再往下看,你会看到

"...OFS="=" /var/tmp/file "

那是它开始的作业。然后它向左看,看到你将它分配给一个任务。并告诉你你得到的错误。

Perl将允许您在插值字符串(允许变量的“字符串化”)中放置双引号,这通常用双引号描述。但您需要使用qq

仔细观察两条线之间的着色:

system("  awk -F" = " '{s[$1]++}{print $1s[$1],$2}' OFS=" = " /var/tmp/file " );
system( qq(awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" /var/tmp/file));

仔细观察第一行,注意字符串的其余部分是偏红色,而等于黑色。它跳出了字符串,你正在处理=作为新令牌。

现在,SO突出显示并不能很好地处理Perl的所有功能,因此qq(运算符未正确突出显示。但如果你忽略它,你会发现引号中的所有内容都显示为引号。如果您相信qq可以将所有内容作为字符串传递,那么您将相信它是所有 SAME 语法单元。