在 file1 中查找包含 file2 中任何关键字的行的最快方法?
Fastest way to find lines in file1 which contains any keywords from file2?
我有两个文件。第一个文件有 30 万条记录,如示例 (file1
),第二个文件有 10 万条记录,如示例 (file2
)。我基本上是用 file1
对 file2
上的每个条目进行 grep 并检索文件 1 中的所有内容。我正在使用普通的 for 循环执行此操作:
for i in `cat file2.txt`; do cat file1 | grep -i -w $i; done > /var/tmp/file3.txt
由于数据太大,我需要 8 个多小时才能完成此操作。我需要你的专业知识,让我可以选择如何以有效的方式在不到 2- 3小时。
示例条目
文件 1
server1:user1:x:13621:22324:User One:/users/user1:/bin/ksh |
server1:user2:x:14537:100:User two:/users/user2:/bin/bash |
server1:user3:x:14598:24:User three:/users/user3:/bin/bash |
server1:user4:x:14598:24:User Four:/users/user4:/bin/bash |
server1:user5:x:14598:24:User Five:/users/user5:/bin/bash |
文件 2
user1
user2
user3
试一试。
测试数据:
%_Host@User> head file1.txt file2.txt
==> file1.txt <==
server1:user1:x:13621:22324:User One:/users/user1:/bin/ksh |
server1:user2:x:14537:100:User two:/users/user2:/bin/bash |
server1:user3:x:14598:24:User three:/users/user3:/bin/bash |
server1:user4:x:14598:24:User Four:/users/user4:/bin/bash |
server1:user5:x:14598:24:User Five:/users/user5:/bin/bash |
==> file2.txt <==
user1
user2
user3
#user4
%_Host@User>
输出:
%_Host@User> ./2comp.pl file1.txt file2.txt ; cat output_comp
server1:user1:x:13621:22324:User One:/users/user1:/bin/ksh |
server1:user3:x:14598:24:User three:/users/user3:/bin/bash |
server1:user2:x:14537:100:User two:/users/user2:/bin/bash |
%_Host@User>
%_Host@User>
脚本: 请再试一次。 Re-check 文件顺序。首先是 File1,然后是第二个文件:./2comp.pl file1.txt file2.txt
。
%_Host@User> cat 2comp.pl
#!/usr/bin/perl
use strict ;
use warnings ;
use Data::Dumper ;
my ($file2,$file1,$output) = (@ARGV,"output_comp") ;
my (%hash,%tmp) ;
(scalar @ARGV != 2 ? (print "Need 2 files!\n") : ()) ? exit 1 : () ;
for (@ARGV) {
open FH, "<$_" || die "Cannot open $_\n" ;
while (my $line = <FH>){$line =~ s/^.+[()].+$| +?$//g ; chomp $line ; $hash{$_}{$line} = "$line"}
close FH ;}
open FH, ">>$output" || die "Cannot open outfile!\n" ;
foreach my $k1 (keys %{$hash{$file1}}){
foreach my $k2 (keys %{$hash{$file2}}){
if ($k2 =~ m/^.+?$k1.+?$/i){ # Case Insensitive matching.
if (!defined $tmp{"$hash{$file2}{$k2}"}){
print FH "$hash{$file2}{$k2}\n" ;
$tmp{"$hash{$file2}{$k2}"} = 1 ;
}}}} close FH ;
# End.
%_Host@User>
谢谢祝你好运。
我有两个文件。第一个文件有 30 万条记录,如示例 (file1
),第二个文件有 10 万条记录,如示例 (file2
)。我基本上是用 file1
对 file2
上的每个条目进行 grep 并检索文件 1 中的所有内容。我正在使用普通的 for 循环执行此操作:
for i in `cat file2.txt`; do cat file1 | grep -i -w $i; done > /var/tmp/file3.txt
由于数据太大,我需要 8 个多小时才能完成此操作。我需要你的专业知识,让我可以选择如何以有效的方式在不到 2- 3小时。
示例条目
文件 1
server1:user1:x:13621:22324:User One:/users/user1:/bin/ksh |
server1:user2:x:14537:100:User two:/users/user2:/bin/bash |
server1:user3:x:14598:24:User three:/users/user3:/bin/bash |
server1:user4:x:14598:24:User Four:/users/user4:/bin/bash |
server1:user5:x:14598:24:User Five:/users/user5:/bin/bash |
文件 2
user1
user2
user3
试一试。
测试数据:
%_Host@User> head file1.txt file2.txt
==> file1.txt <==
server1:user1:x:13621:22324:User One:/users/user1:/bin/ksh |
server1:user2:x:14537:100:User two:/users/user2:/bin/bash |
server1:user3:x:14598:24:User three:/users/user3:/bin/bash |
server1:user4:x:14598:24:User Four:/users/user4:/bin/bash |
server1:user5:x:14598:24:User Five:/users/user5:/bin/bash |
==> file2.txt <==
user1
user2
user3
#user4
%_Host@User>
输出:
%_Host@User> ./2comp.pl file1.txt file2.txt ; cat output_comp
server1:user1:x:13621:22324:User One:/users/user1:/bin/ksh |
server1:user3:x:14598:24:User three:/users/user3:/bin/bash |
server1:user2:x:14537:100:User two:/users/user2:/bin/bash |
%_Host@User>
%_Host@User>
脚本: 请再试一次。 Re-check 文件顺序。首先是 File1,然后是第二个文件:./2comp.pl file1.txt file2.txt
。
%_Host@User> cat 2comp.pl
#!/usr/bin/perl
use strict ;
use warnings ;
use Data::Dumper ;
my ($file2,$file1,$output) = (@ARGV,"output_comp") ;
my (%hash,%tmp) ;
(scalar @ARGV != 2 ? (print "Need 2 files!\n") : ()) ? exit 1 : () ;
for (@ARGV) {
open FH, "<$_" || die "Cannot open $_\n" ;
while (my $line = <FH>){$line =~ s/^.+[()].+$| +?$//g ; chomp $line ; $hash{$_}{$line} = "$line"}
close FH ;}
open FH, ">>$output" || die "Cannot open outfile!\n" ;
foreach my $k1 (keys %{$hash{$file1}}){
foreach my $k2 (keys %{$hash{$file2}}){
if ($k2 =~ m/^.+?$k1.+?$/i){ # Case Insensitive matching.
if (!defined $tmp{"$hash{$file2}{$k2}"}){
print FH "$hash{$file2}{$k2}\n" ;
$tmp{"$hash{$file2}{$k2}"} = 1 ;
}}}} close FH ;
# End.
%_Host@User>
谢谢祝你好运。