Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在perl中比较两个文本文件并删除匹配的内容并传递到输出?_Perl_File_Compare - Fatal编程技术网

如何在perl中比较两个文本文件并删除匹配的内容并传递到输出?

如何在perl中比较两个文本文件并删除匹配的内容并传递到输出?,perl,file,compare,Perl,File,Compare,我有两个文本文件text1.txt和text2.txt,如下所示 text1 ac abc abcd abcde text2 ab abc acd abcd 输出 ac abcde 当第二个文件中存在匹配项时,我需要比较这两个文件并从text1中删除内容 我想要Perl中的代码。目前我正在尝试下面的代码 #!usr/bin/perl use strict; use warnings; open (GEN, "text1.tx

我有两个文本文件text1.txt和text2.txt,如下所示

text1

    ac
    abc
    abcd
    abcde
text2

    ab
    abc
    acd
    abcd
输出

ac
abcde
当第二个文件中存在匹配项时,我需要比较这两个文件并从
text1
中删除内容

我想要Perl中的代码。目前我正在尝试下面的代码

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

open (GEN, "text1.txt") || die ("cannot open general.txt");
open (SEA, "text2.txt") || die ("cannot open search.txt");
open (OUT,">> output.txt") || die ("cannot open intflist.txt");
open (LOG, ">> logfile.txt");

undef $/;
foreach (<GEN>) {

  my $gen = $_;
  chomp ($gen);
  print LOG $gen;

  foreach (<SEA>) {

    my $sea = $_;
    chomp($sea);
    print LOG $sea;

    if($gen ne $sea) {
      print OUT $gen;
    }
  }
}
#!usr/bin/perl
严格使用;
使用警告;
打开(GEN,“text1.txt”)| | die(“无法打开general.txt”);
open(SEA,“text2.txt”)| | die(“cannotopensearch.txt”);
open(OUT,“>>output.txt”)| | die(“无法打开intflist.txt”);
打开(LOG,“>>logfile.txt”);
未定义$/;
foreach(){
my$gen=$\;
chomp($gen);
打印日志$gen;
foreach(){
我的$sea=$\;
咀嚼(海);
打印日志$sea;
如果($gen ne$sea){
打印$gen;
}
}
}

在这里,我从
text1
获取所有内容,而不是不匹配的内容。请帮帮我

我认为您应该读取数组中的text2,然后在该数组的第二个foreach中使用数组

@b = <SEA>;
@b=;

或者在第二个循环中,文件指针已经在末尾了

我认为应该读取数组中的text2,然后在该数组的第二个foreach中使用数组

@b = <SEA>;
@b=;
否则,在第二个循环中,文件指针将以一种方式位于末尾:

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

$\="\n";

open my $fh1, '<', 'file1' or die $!;
open my $fh2, '<', 'file2' or die $!;
open my $out, '>', 'file3' or die $!;

chomp(my @arr1=<$fh1>);
chomp(my @arr2=<$fh2>);

foreach my $x (@arr1){
        print $out $x if (!grep (/^\Q$x\E$/,@arr2));
}

close $fh1;
close $fh2;
close $out;
单向:

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

$\="\n";

open my $fh1, '<', 'file1' or die $!;
open my $fh2, '<', 'file2' or die $!;
open my $out, '>', 'file3' or die $!;

chomp(my @arr1=<$fh1>);
chomp(my @arr2=<$fh2>);

foreach my $x (@arr1){
        print $out $x if (!grep (/^\Q$x\E$/,@arr2));
}

close $fh1;
close $fh2;
close $out;
这是我的计划:

  • 读取散列中第一个文件的内容,并使用出现次数计数器。例如,使用您获得的数据:

    %lines = ( 'ac' => 1,
        'abc' => 1,
        'abcd' => 1,
        'abcde' => 1);
    
  • 读取第二个文件,如果密钥存在,则删除前面的哈希%行

  • 将键
    %行
    打印到所需文件
  • 例如:

     use strict;
    
     open my $fh1, '<', 'text1' or die $!;
     open my $fh2, '<', 'text2' or die $!;
     open my $out, '>', 'output' or die $!;
     my %lines = ();
    
     while( my $key = <$fh1> ) {
        chomp $key;
        $lines{$key} = 1;
     }
    
     while( my $key = <$fh2> ) {
        chomp $key;
        delete $lines{$key};
     }
    
     foreach my $key(keys %lines){
        print $out $key, "\n";
     }
    
     close $fh1;
     close $fh2;
     close $out;
    
    使用严格;
    打开我的$fh1,“这是我的计划:

  • 读取散列中第一个文件的内容,并使用出现次数计数器。例如,使用您获得的数据:

    %lines = ( 'ac' => 1,
        'abc' => 1,
        'abcd' => 1,
        'abcde' => 1);
    
  • 读取第二个文件,如果密钥存在,则删除前面的哈希%行

  • 将键
    %行
    打印到所需文件
  • 例如:

     use strict;
    
     open my $fh1, '<', 'text1' or die $!;
     open my $fh2, '<', 'text2' or die $!;
     open my $out, '>', 'output' or die $!;
     my %lines = ();
    
     while( my $key = <$fh1> ) {
        chomp $key;
        $lines{$key} = 1;
     }
    
     while( my $key = <$fh2> ) {
        chomp $key;
        delete $lines{$key};
     }
    
     foreach my $key(keys %lines){
        print $out $key, "\n";
     }
    
     close $fh1;
     close $fh2;
     close $out;
    
    使用严格;
    
    打开my$fh1,“您的主要问题是未定义输入记录分隔符
    $/
    。这意味着整个文件将作为单个字符串读取,您所能做的就是说这两个文件是不同的

    删除
    undef$/
    ,事情就会好得多。但是,内部
    for
    循环将读取并打印
    文件2
    中与
    文件1
    的第一行不匹配的所有行。第二次遇到此循环时,所有数据都已从文件中读取,因此根本不会执行循环体。您必须在外部循环中打开
    file2
    ,或者将文件读入数组并在其上循环

    然后,您真的要打印
    file2
    中与
    file1
    中的每一行不相等的所有行吗

    更新

    正如我在评论中所写的,听起来您想输出
    text1
    中没有出现在
    text2
    中的行。使用散列很容易实现这一点:

    use strict;
    use warnings;
    
    my %exclude;
    
    open my $fh, '<', 'text2.txt' or die $!;
    while (<$fh>) {
      chomp;
      $exclude{$_}++;
    }
    
    open $fh, '<', 'text1.txt' or die $!;
    while (<$fh>) {
      chomp;
      print "$_\n" unless $exclude{$_};
    }
    

    您的主要问题是未定义输入记录分隔符
    $/
    。这意味着整个文件将作为单个字符串读取,您所能做的就是说这两个文件是不同的

    删除
    undef$/
    ,事情就会好得多。但是,内部
    for
    循环将读取并打印
    文件2
    中与
    文件1
    的第一行不匹配的所有行。第二次遇到此循环时,所有数据都已从文件中读取,因此根本不会执行循环体。您必须在外部循环中打开
    file2
    ,或者将文件读入数组并在其上循环

    然后,您真的要打印
    file2
    中与
    file1
    中的每一行不相等的所有行吗

    更新

    正如我在评论中所写的,听起来您想输出
    text1
    中没有出现在
    text2
    中的行。使用散列很容易实现这一点:

    use strict;
    use warnings;
    
    my %exclude;
    
    open my $fh, '<', 'text2.txt' or die $!;
    while (<$fh>) {
      chomp;
      $exclude{$_}++;
    }
    
    open $fh, '<', 'text1.txt' or die $!;
    while (<$fh>) {
      chomp;
      print "$_\n" unless $exclude{$_};
    }
    

    我想这样看待你的问题:

    open my $FILE, "<", "file.txt" or die "Can't open file.txt: $!";
    my $line_no = 1;
    my %Set = map {$_ => $line_no++} <$FILE>;
    
    • file.txt
      中有一组字符串
    • 您在
      禁用的.txt
      中有一组F个禁用字符串
    • 您需要允许的字符串,因此S\F(set减号)
    Perl中有一个数据结构,它实现了一组字符串:散列。(它也可以映射到标量,但这是次要的)

    首先,我们创建一组线。我们让该文件中的所有字符串映射到
    unde
    ,因为我们不需要该值:

    open my $FILE, "<", "file.txt" or die "Can't open file.txt: $!";
    my %Set = map {$_ => undef} <$FILE>;
    
  • 结果集R最初是S。对于F中的每个元素,我们从R中删除该项:

  • (键
    函数访问字符串集中的元素)

    然后我们可以打印出所有键:
    打印键%Result

    但是如果我们想维持秩序呢?散列中的条目也可以携带一个关联的值,那么为什么行号不能呢?我们创建的集合如下所示:

    open my $FILE, "<", "file.txt" or die "Can't open file.txt: $!";
    my $line_no = 1;
    my %Set = map {$_ => $line_no++} <$FILE>;
    

    打开我的$FILE,“我想这样看待您的问题:

    open my $FILE, "<", "file.txt" or die "Can't open file.txt: $!";
    my $line_no = 1;
    my %Set = map {$_ => $line_no++} <$FILE>;
    
    • file.txt
      中有一组字符串
    • 您在
      禁用的.txt
      中有一组F个禁用字符串
    • 您需要允许的字符串,因此S\F(set减号)
    Perl中有一个数据结构,它实现了一组字符串:散列(它也可以映射到标量,但这在这里是次要的)

    因此,首先我们创建我们拥有的一组行。我们让该文件中的所有字符串映射到
    unde
    ,因为我们不需要该值:

    open my $FILE, "<", "file.txt" or die "Can't open file.txt: $!";
    my %Set = map {$_ => undef} <$FILE>;
    
  • 结果集R最初是S。对于F中的每个元素,我们从R中删除该项:

  • <