从grep到perl:perl的反向匹配

从grep到perl:perl的反向匹配,perl,grep,Perl,Grep,这是相当长的一段时间,我没有在perl编程,我需要一些推动 我需要比较两个列表,以便只保留不匹配的行 我的第一个文件如下所示: 1 pf1 er2 0,4 2 pf1 er3 0,56 3 pf1 er6 072365 4 er3 pf3 0263 5 pf5 er2 028473 第二个文件类似于: pf1-er2 pf1-er3 er2-pf1 er3-pf1 我希望得到如下输出: 3 pf1 er6 072365 4 er3 pf3 0263 5 pf5 er2 028473 我以前

这是相当长的一段时间,我没有在perl编程,我需要一些推动

我需要比较两个列表,以便只保留不匹配的行

我的第一个文件如下所示:

1 pf1 er2 0,4
2 pf1 er3 0,56
3 pf1 er6 072365
4 er3 pf3 0263
5 pf5 er2 028473
第二个文件类似于:

pf1-er2
pf1-er3
er2-pf1
er3-pf1
我希望得到如下输出:

3 pf1 er6 072365
4 er3 pf3 0263
5 pf5 er2 028473
我以前是通过
grep-Fvf second_file.txt first-file.txt>output.txt

现在我需要在perl中执行同样的操作,但我无法组织代码

open(HAN,“<$file_1”)| | | die“不可能的aprire il文件$file_1”;
@r=;
接近(汉族);
打开(RES,“<$file_2”)| |死“不可能的aprire il文件$file_2”;
@c=;
关闭(RES);

对于($i=0;$i,这里有一个不是很详细但很有效的解决方案:

    #!/usr/bin/env perl 

use strict;
use warnings;
use 5.010;
use Data::Dumper;

#my @first_file_lines = split "\n", `cat ./first_file.txt`;
#my @second_file_lines = split "\n",`cat ./second_file.txt`;
open( my $fh, '<', './first_file.txt' );
open( my $fh1, '<', './second_file.txt' );
chomp ( my @first_file_lines = <$fh> );
chomp (my @second_file_lines = <$fh1>) ;

close( $fh );
close( $fh1 );


my @output = grep { filter( $_, \@second_file_lines ) } @first_file_lines;

sub filter {
    my $current    = shift;
    my $compare_to = shift;

    for my $comp ( @$compare_to ) {
        my $comp1 = $comp;
        $comp1 =~ s/\|/ /;
        if ( $current =~ /^$comp1/ ) {
            say 'equal: ' . "$current   :  $comp";
            return;
        }
    }


    return $current;
}

say Dumper( @first_file_lines );
say Dumper( @second_file_lines );

for my $out ( @output ) {
    `echo "$out" >> ./output.txt`;
}
!/usr/bin/env perl
严格使用;
使用警告;
使用5.010;
使用数据::转储程序;
#我的@first_file_lines=split“\n”,`cat./first_file.txt`;
#我的@second_file_line=split“\n”,`cat./second_file.txt`;

open(my$fh,“这里有一个不是很详细但很有效的解决方案:

    #!/usr/bin/env perl 

use strict;
use warnings;
use 5.010;
use Data::Dumper;

#my @first_file_lines = split "\n", `cat ./first_file.txt`;
#my @second_file_lines = split "\n",`cat ./second_file.txt`;
open( my $fh, '<', './first_file.txt' );
open( my $fh1, '<', './second_file.txt' );
chomp ( my @first_file_lines = <$fh> );
chomp (my @second_file_lines = <$fh1>) ;

close( $fh );
close( $fh1 );


my @output = grep { filter( $_, \@second_file_lines ) } @first_file_lines;

sub filter {
    my $current    = shift;
    my $compare_to = shift;

    for my $comp ( @$compare_to ) {
        my $comp1 = $comp;
        $comp1 =~ s/\|/ /;
        if ( $current =~ /^$comp1/ ) {
            say 'equal: ' . "$current   :  $comp";
            return;
        }
    }


    return $current;
}

say Dumper( @first_file_lines );
say Dumper( @second_file_lines );

for my $out ( @output ) {
    `echo "$out" >> ./output.txt`;
}
!/usr/bin/env perl
严格使用;
使用警告;
使用5.010;
使用数据::转储程序;
#我的@first_file_lines=split“\n”,`cat./first_file.txt`;
#我的@second_file_line=split“\n”,`cat./second_file.txt`;
打开(我的$fh,这应该可以:

  • 从引用文件中读取行
    • 引用该行的内容,使其与从中编译正则表达式兼容
  • 编译一个组合正则表达式,将所有匹配项组合在一起
    • 例如,您的示例是
      (?:pf1 er2 | pf1 er3 | er2 pf1 | er3 pf1)
  • 从标准文本中读取行
    • 除非正则表达式匹配,否则将行打印到标准输出
!/usr/bin/perl
严格使用;
使用警告;
我的($reference)=@ARGV;
我的$fh;
打开($fh),这应该可以:

  • 从引用文件中读取行
    • 引用该行的内容,使其与从中编译正则表达式兼容
  • 编译一个组合正则表达式,将所有匹配项组合在一起
    • 例如,您的示例是
      (?:pf1 er2 | pf1 er3 | er2 pf1 | er3 pf1)
  • 从标准文本中读取行
    • 除非正则表达式匹配,否则将行打印到标准输出
!/usr/bin/perl
严格使用;
使用警告;
我的($reference)=@ARGV;
我的$fh;

open($fh,“基于该样本数据,如果第二列和第三列与第二个文件行的第一列和第二列匹配,则希望从第一个文件中排除行。将第二个文件的列存储在散列中,然后在读取第一个文件时检查这些键的存在是一种简单、非常省时的方法:

#!/usr/bin/perl
use warnings;
use strict;
use autodie;

my ($data_file, $excludes_file) = @ARGV;

my %excludes;
open my $ex, "<", $excludes_file;
while (<$ex>) {
  chomp;
  my @F = split;
  $excludes{$F[0]}->{$F[1]} = 1;
}

open my $data, "<", $data_file;
while (<$data>) {
  my @F = split;
  print unless exists $excludes{$F[1]}->{$F[2]};
}

基于该示例数据,如果第二列和第三列与第二个文件的行的第一列和第二列相匹配,则希望从第一个文件中排除行。将第二个文件的列存储在哈希中,然后在读取第一个文件时检查这些键是否存在是一种简单、非常省时的方法:

#!/usr/bin/perl
use warnings;
use strict;
use autodie;

my ($data_file, $excludes_file) = @ARGV;

my %excludes;
open my $ex, "<", $excludes_file;
while (<$ex>) {
  chomp;
  my @F = split;
  $excludes{$F[0]}->{$F[1]} = 1;
}

open my $data, "<", $data_file;
while (<$data>) {
  my @F = split;
  print unless exists $excludes{$F[1]}->{$F[2]};
}


你已经编写了什么Perl代码,它如何不执行<代码> GRP代码的操作?请参阅如何运行Perl的基础知识。好的第一步很可能考虑什么是<代码> GRP命令,以及在散文中的解释。然后,把这篇散文作为一个程序重写。@ CyIon我用草稿编辑了我的问题。在我为grep编写的代码中,第二个文件不能使用
。也许是``?为什么
for
中,而
中?为什么当你已经将它清空到
@c
中(并关闭了它!)时,它还要尝试读取
首先,我要做的是添加<代码>使用严格;和<代码>使用警告;< /Cord>。然后修复您将得到的错误。您已经编写了什么Perl代码,以及如何不执行<代码> GRP代码。查看如何运行Perl的基础知识。好的第一步很可能考虑<代码> GRP命令。然后,用散文来解释。然后,把那篇散文作为一个程序重写。@Corion我用我为grep编写的代码草稿编辑了我的问题,第二个文件不能使用
。也许是``?为什么
while
for
中?为什么你已经清空了它却试图读取
将其插入
@c
(并将其关闭!)?我要做的第一件事是添加
使用严格;
使用警告;
。然后修复您将遇到的错误。谢谢,但我在windows计算机上,无法使用“cat”。我编辑了代码。您可以使用Perl内置的open来读取文件。写入文件也是如此。open(my$fh,“>”,“./output.txt”);作为输出,我只得到文件1的内容谢谢,但我在windows机器上,不能使用“cat”.I编辑了代码。您可以使用Perl内置的open来读取文件。这同样适用于写入文件。open(my$fh,“>”,“./output.txt”);作为输出,我只得到文件1content@Gabelins更新我的答案以提高效率,即只进行一次正则表达式匹配。更新答案以充当筛选器,即筛选器的输入通过STDIN传入(请参见命令行示例)@Gabelins更新了我的答案以提高效率,即只进行一次正则表达式匹配。更新了答案以充当筛选器,即筛选器的输入通过STDIN传入(请参见命令行示例)。