使用Perl比较一组字符串和文件

时间:2014-08-14 11:30:37

标签: arrays regex perl

我正在尝试编写一个Perl脚本,它将找出一组字符串和一个文件之间的区别,并且我想打印与该字符串不匹配的文件内容。

我的INPUT1将是:(字符串集)

AAAAA
BBBBB
CCCCC
DDDDD
EEEEE   --- These are user ids which should be passed in the script

我的INPUT2将是一个User.txt文件,其中包含许多ID,包括上面提到的那些

ABBAAA
ACARVAV
AAAAA
BBBBB
CCCCC
DDDDD
EEEEE
BGATA
ETYUIOL

我希望我的输出像

ABBAAA
ACARVAV
BGATA
ETYUIOL

到目前为止,我已到达

my @things_to_find = qw(AAAAAA BBBBB CCCCC DDDDD EEEEE);
my $comparefile = "User.txt";
open ( my $compare_filehandle, "<", $comparefile ) or die $!;
while ( my $line = <$compare_filehandle> ) 
{
    foreach my $thing ( @things_to_find )
    {
        print "Match found with: $line" if $line !~ /$thing/;
    }
}

但这并没有产生所需的输出。我是Perl的新手,所以你的任何建议都对我很有帮助。

4 个答案:

答案 0 :(得分:2)

尝试使用:

use List::Util qw(none);
my @things_to_find = qw(AAAAAA BBBBB CCCCC DDDDD EEEEE);
my $comparefile = "User.txt";
open ( my $compare_filehandle, "<", $comparefile ) or die $!;
while ( my $line = <$compare_filehandle> ) 
{
    print $line if none { $line =~ /\b$_\b/}  @things_to_find;
}

文档List::Util

答案 1 :(得分:1)

您可以尝试使用这个简单的grep来匹配模式。

use strict;
use warnings;
use autodie;

my @users = qw(AAAAAA BBBBB CCCCC DDDDD EEEEE);

my $file = "User.txt";
open my $fh, "<", $file;
while ( my $line = <$fh> ) {
    chomp $line;
    print "Matched line : $line\n" unless grep {$line eq $_} @users;
}

注意:
要搜索模式,请使用grepmap优于foreachfor

答案 2 :(得分:1)

按照目前的情况,您自己的代码会找到文件中不包含列表中所有字符串的所有行,而不应该不要等于这些字符串的任何。您需要将包含测试更改为相等测试;一找到匹配就跳过字符串;并使用chomp从文件中读取的字符串中删除尾部换行符。

有两种明显的方法可以写出来。第一个是构建哈希,它实际上是一个由字符串而不是整数索引的数组。如果使用文件中的条目填充哈希值,然后删除字符串数组中的条目。这看起来像这样

use strict;
use warnings;

my $comparefile = 'User.txt';
my @users = qw/ AAAAA BBBBB CCCCC DDDDD EEEEE /;

open my $users_fh, '<', $comparefile or die $!;

my %file_users;
while (my $user = <$users_fh> ) {
  chomp $user;
  $file_users{$user} = 1;
}

delete $file_users{$_} for @users;

print "$_\n" for sort keys %file_users;

<强>输出

ABBAAA
ACARVAV
BGATA
ETYUIOL

另一种方法是从字符串构建正则表达式,并使用它从文件中选择要忽略的那些行。这看起来像下面的程序,输出与前一个程序的输出相同。此解决方案会更快,但包含一些更高级的想法,如正则表达式和map,因此您可能更喜欢第一个。

use strict;
use warnings;

my $comparefile = 'User.txt';
my @users = qw/ AAAAA BBBBB CCCCC DDDDD EEEEE /;

my $re = join '|', map "^\Q$_\E\$", @users;
$re = qr/$re/;

open my $users_fh, '<', $comparefile or die $!;

my @file_users;
while (my $user = <$users_fh> ) {
  chomp $user;
  push @file_users, $user unless $user =~ $re;
}

print "$_\n" for sort @file_users;

答案 3 :(得分:0)

use strict;
use warnings;
use autodie;

open my $in, '<', 'in.txt'; 
open my $in2, '<', 'in_2.txt';

my (%data1, %data2);
while(<$in>){
    chomp;
    $data1{$_} = 1;
}

while(<$in2>){
    chomp;
    $data2{$_} = 2;
}


foreach(sort keys %data2){
    print "$_\n" unless $data1{$_};
}