如何在perl中比较两个文本文件并删除匹配的内容并传递到输出?
我有两个文本文件text1.txt和text2.txt,如下所示 text1如何在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
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中删除该项:
<