【问题标题】:Combining two one line Perl commands into a script将两个单行 Perl 命令组合成一个脚本
【发布时间】:2013-03-11 16:29:30
【问题描述】:

我正在尝试将以下两个单行 perl 代码组合成一个 perl 脚本,该脚本在文件的一行上执行,然后再进入下一行。请注意,这不是我自己的原始代码,这里提供的非常周到:Adding a blank line between unrelated data entries

1

perl -pae 'print $/ if (defined $x && $x ne $F[0]); $x = $F[0];' DF-data2pfa.csv >DF-data2pfb.txt

2

perl -pae 'print $/ if (defined $x && $x ne $F[3]); $x = $F[3];' DF-data2pfb.txt >DF-data2pfc.txt

该脚本完全符合我的要求(将我的数据集中一行的 F[0] 字段与前一行的 F[0] 进行比较,如果它们不同,则在这些条目之间添加一个空白行),除了我意识到我需要它在一行上查看 F[0]F[3] 并将两者与前一行进行比较。令我尴尬的是,我尝试一个接一个地运行,并没有意识到每次脚本遇到前一个脚本添加的空行时都会添加一个额外的空行,这对于我正在尝试输入的程序来说是不可接受的数据到。

所以我尝试使用Deparse 工具将两者都转换为脚本格式,然后使用elsif 语句将第二个添加到第一个。这变得一团糟。另外我不确定如何在脚本中实现命令行的pae功能。我不确定脚本中是否需要e,但似乎首先打印每一行然后将其拆分为一个数组(使用pa)是整个代码的一个相当完整的组件,我不确定如何在这里实现。

这是我得到的:

while (defined($_ = <ARGV>)) {
    our(@F) = split(' ', $_, 0);
$x = $F[0];
$y = $F[3];
if defined $x and $x ne $F[0];
elsif defined $y and $y ne $F[3];
   print $/ 
}
continue {
    die "-p destination: $!\n" unless print $_;
}

如果这里没有必要,我也愿意不使用deparse 模块。感谢您提供的任何帮助/解释!

【问题讨论】:

    标签: perl if-statement


    【解决方案1】:

    单行话有点啰嗦,但你可以这样做:

    perl -pae 'print $/ if ((defined $x && $x ne $F[0]) && (defined $y && $y ne $F[3])); $x = $F[0]; $y = $F[3]' DF-data2pfa.csv >DF-data2pfb.txt
    

    或作为脚本

    open my $fh, "<", "input_file_name";
    open my $out, ">", "output_file_name";
    my ($x, $y);
    foreach (<$fh>) {
        my @F = split(' ', $_);
        if ( ( defined($x) && $x ne $F[0] ) && (defined($y) && $y ne $F[3]) ) {
            print $OUT $\;
        }
        $x = $F[0];
        $y = $F[3];
        print $OUT $_;
    }
    

    我不确定我是否正确阅读了您的要求 - 如果您需要在 $F[0] 或 $F[3] 与上一行匹配时打印额外的行,那么条件将是:

    ( ( defined($x) && $x ne $F[0] ) || (defined($y) && $y ne $F[3]) )
    

    【讨论】:

    • 啊,是的,我可能没有连贯地解释它。我最终用您列出的最后一个条件修改了您放置的单行。效果如我所愿,非常感谢。
    【解决方案2】:

    我不能 100% 确定你在做什么,所以这个脚本可能不是你想要的,但它希望可以帮助你开始。它使用strictwarnings 编译指示来帮助您防止某些错误。

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    my ($x, $y, @F);
    while ( <> ) {
      @F = split ' ';
      if ( defined $x and $x ne $F[0] ) {
        print $/;
      } elsif ( defined $y and $y ne $F[3] ) {
        print $/;
      }
      $x = $F[0];
      $y = $F[3];
      print;
    }
    

    这隐式使用了$_ 变量(while 隐式设置它,split 隐式使用它)。它还显示了条件语句的外观;当不用于 posfix 风格时,条件需要圆括号。我已经离开 continue 块,但实际上我从来不需要使用一个,这可能是 deparse 的残余,可能会在 while 循环结束时进行(并且 print 可以隐式使用 $_也)。最后&lt;&gt;操作符是magic-open/read操作符,它将顺序使用ARGV中的文件或根据需要使用STDIN。

    如果您需要更多帮助,只需 ping。

    【讨论】:

    • 您可以将文件名传递给脚本perl scriptname.pl file1 file2 ...,也可以通过管道将其传递给cat file1 | perl scriptname。两者都行。
    • 如果你想谷歌的话,它被称为“钻石算子”的“魔法开放”属性。它也记录在perldoc perlop的这一部分中。
    • 呸,我应该意识到的。好吧,现在我将文件名传递给脚本,但它似乎只是重新打印整个文件,不管我在# do something cmets 下面放了什么。我需要在 ifelsif 语句下方进行特定数量的缩进吗?
    • 我已经更新,所以我的代码(应该)和 RickF 的代码块一样。不,就像大多数类似 C 的语言一样,空格对解释器来说是没有意义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 2014-10-02
    • 2012-07-22
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多