1

我正在尝试将以下两个单行 perl 代码组合成一个 perl 脚本,该脚本在文件的一行上执行,然后再进入下一行。请注意,这不是我自己的原始代码,这里提供的非常周到:在不相关的数据条目之间添加空白行

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脚本中是否有必要,但似乎首先打印每一行,然后将其拆分为一个数组( with 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模块。感谢您提供的任何帮助/解释!

4

2 回答 2

2

对于单行来说,它有点罗嗦,但你可以这样做:

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]) )
于 2013-03-11T17:15:55.840 回答
1

我不是 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 也可以隐式使用$_)。最后这个<>操作符是magic-open/read操作符,它会按顺序使用ARGV中的文件或者根据需要使用STDIN。

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

于 2013-03-11T17:15:02.313 回答