我希望比赛能够发生,但事情并没有发生。
我有一个问题。我希望在另一个文件中找到行的出现。
这是一个文件(@file)
735 1 1
1891 1 0
2021 1 1
1892 2 1
667 1 0
802 2 1
665 1 0
666 1 1
596 1 0
3193 2 1
这是我必须在上面找到的行(@ file1)
1521 1 0 : 1167 0 0 : 1167 2 0 : 1167 1 0 ;
2605 1 1 ;
2280 0 1 : 2280 2 0 : 1892 0 0 : 2280 1 0 : 2021 0 0 ;
1892 2 1 : 667 0 1 : 667 1 0 ;
1892 1 1 ;
这是我写的代码
foreach $leadline (@file1) {
foreach $line (@file) {
$_ = ' ' . $leadline;
$line = ' ' . $line;
if (m/$line/) {
push @final, $_;
}
}
}
但我无法检测到这些线条。
@file1
和@file
变量存储文件的内容。
我要么没有检测到线路,要么检测到所有线路。
我在两行之前连接空格的原因是,有时667 1 0可以作为给定行中的第一个短语出现。我不熟悉Regex直接在Regex中执行此操作。
注意: - 如果第一个文件中的第i行和第j行作为另一个文件的同一行中的模式出现,则输出应该只是其中一行。此外,如果找到模式1667 1 0,则不应将其与667 1 0混淆。因此,我添加了空格。
我能够在Python中实现这一目标,但无法在Perl中复制它。这是Python片段: -
for line1 in file1:
for j in range(0,len(file0)-1):# in file0:
if ' '+lines[j][0:len(file0[j])-1] in ' '+line1:
i = i + 1
print line1[0:len(line1)-1]
break
预期产量为: - 1892 2 1:667 0 1:667 1 0;
答案 0 :(得分:1)
您可以通过|
加入来自file1的行(并在每个上应用quotemeta
)来创建正则表达式。 \b
应阻止667
中的1667
匹配。
#!/usr/bin/perl
use warnings;
use strict;
my @search;
open my $F1, '<', 'file1' or die $!;
while (<$F1>) {
chomp;
push @search, quotemeta;
}
my $regex = join '|', @search;
$regex = qr/\b(?:$regex)\b/;
open my $F2, '<', 'file2' or die $!;
while (<$F2>) {
print if /$regex/;
}
答案 1 :(得分:1)
我现在认为这是解决另一个问题的方法,但无论如何它都在这里!
use warnings;
use strict;
use 5.010;
use Array::Utils 'array_diff';
open my $fh, '<', 'f1.txt' or die $!;
my @f1;
while ( <$fh> ) {
push @f1, [split];
}
my @final;
open $fh, '<', 'f2.txt' or die $!;
while ( <$fh> ) {
my @f2 = map [ /\d+/g ], split /:/;
for my $f1 ( @f1 ) {
my @matches = grep { not array_diff(@$f1, @$_) } @f2;
push @final, map "@$_", @matches;
}
}
say for @final;
<强>输出强>
1892 2 1
667 0 1
667 1 0
<强>更新强>
好的,这是我的第二次尝试!这基本上是choroba
wrote,但是使用map
并且在第一个文件的数据上添加了剥离所有尾随空格。
use warnings;
use strict;
use 5.014; # For non-destructive substitution
open my $fh, '<', 'f1.txt' or die $!;
my @f1 = map s/\s+\z//r, <$fh>;
my $re = join '|', @f1;
open $fh, '<', 'f2.txt' or die $!;
my @final = grep /\b(?:$re)\b/, <$fh>;
print for @final;
<强>输出强>
1892 2 1 : 667 0 1 : 667 1 0 ;
答案 2 :(得分:1)
以下是我的工作方式:
use Modern::Perl;
use Data::Dumper;$Data::Dumper::Indent = 1;
my @file = (
'735 1 1',
'1891 1 0',
'2021 1 1',
'1892 2 1',
'667 1 0',
'802 2 1',
'665 1 0',
'666 1 1',
'596 1 0',
'3193 2 1',
);
my @final;
while(my $line = <DATA>) {
chomp $line;
if (grep{$line =~ /\b$_\b/} @file) {
push @final, $line;
}
}
say Dumper\@final;
__DATA__
1521 1 0 : 1167 0 0 : 1167 2 0 : 1167 1 0 ;
2605 1 1 ;
2280 0 1 : 2280 2 0 : 1892 0 0 : 2280 1 0 : 2021 0 0 ;
1892 2 1 : 667 0 1 : 667 1 0 ;
1892 1 1 ;
<强>输出:强>
$VAR1 = [
'1892 2 1 : 667 0 1 : 667 1 0 ; '
];
使用您的文件:
use Modern::Perl;
use Data::Dumper;$Data::Dumper::Indent = 1;
open my $fh, '<', 'file.txt' or die "unable to open 'file.txt': $!";
my @file = <$fh>;
chomp @file;
my @final;
open $fh, '<', 'file1.txt' or die "unable to open 'file1.txt': $!";
while(my $line = <$fh>) {
chomp $line;
if (grep{$line =~ /\b$_\b/} @file) {
push @final, $line;
}
}
say Dumper\@final;