2012-07-15 14 views
10

file.contain.query.txt grep कोफास्ट विकल्प -f

ENST001 

ENST002 

ENST003 

file.to.search.in.txt

ENST001 90 

ENST002 80 

ENST004 50 

क्योंकि ENST003 2 फ़ाइल और ENST004 है में कोई प्रविष्टि नहीं है 1 फ़ाइल में कोई प्रविष्टि की उम्मीद उत्पादन होता है:

ENST001 90 

ENST002 80 

एक विशेष फ़ाइल हम आम तौर पर निम्न कार्य में बहु क्वेरी grep के लिए:

grep -f file.contain.query <file.to.search.in >output.file 

क्योंकि मुझे 10000 क्वेरी और file.to.search.in में लगभग 100000 कच्चे हैं, इसे पूरा करने में बहुत लंबा समय लगता है (5 घंटे की तरह)। क्या grep -f के लिए एक तेज विकल्प है?

+0

आपकी ज़रूरतें क्या हैं? क्या आप पहले फाइल की दूसरी कुंजी के साथ फ़िल्टर की गई दूसरी लाइनों के साथ एक फाइल चाहते हैं? –

+0

मैंने अपेक्षित परिणाम – user1421408

+1

संपादित किया इनपुट इनपुट पुनर्निर्देशन अनावश्यक है। –

उत्तर

10

आप एक शुद्ध पर्ल विकल्प चाहते हैं, एक हैश तालिका में अपनी क्वेरी फ़ाइल कुंजी पढ़ें, फिर उन कुंजियों के खिलाफ मानक इनपुट की जाँच:

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

# build hash table of keys 
my $keyring; 
open KEYS, "< file.contain.query.txt"; 
while (<KEYS>) { 
    chomp $_; 
    $keyring->{$_} = 1; 
} 
close KEYS; 

# look up key from each line of standard input 
while (<STDIN>) { 
    chomp $_; 
    my ($key, $value) = split("\t", $_); # assuming search file is tab-delimited; replace delimiter as needed 
    if (defined $keyring->{$key}) { print "$_\n"; } 
} 

तुम इतनी है कि यह प्रयोग करना होगा:

lookup.pl < file.to.search.txt 

एक हैश तालिका स्मृति भी पर्याप्त मात्रा में ले जा सकते हैं, लेकिन खोजों ज्यादा हैं तेज़ (हैश टेबल लुकअप स्थिर समय में हैं), जो आसान है क्योंकि स्टोर करने के बजाय आपके पास 10 गुना अधिक कुंजी है।

+2

grep -f के साथ तुलना करते समय यह फेरारी है .. धन्यवाद – user1421408

+0

बिल्कुल सही समाधान; +1 –

5

यह पर्ल कोड मई आपकी मदद करता है:

use strict; 
open my $file1, "<", "file.contain.query.txt" or die $!; 
open my $file2, "<", "file.to.search.in.txt" or die $!; 

my %KEYS =(); 
# Hash %KEYS marks the filtered keys by "file.contain.query.txt" file 

while(my $line=<$file1>) { 
    chomp $line; 
    $KEYS{$line} = 1; 
} 

while(my $line=<$file2>) { 
    if($line =~ /(\w+)\s+(\d+)/) { 
     print "$1 $2\n" if $KEYS{$1}; 
    } 
} 

close $file1; 
close $file2; 
+0

आप सिस्को के वापसी मूल्य की जांच करना भूल गए हैं। – tchrist

1

Mysql:

Mysql में डेटा आयात या इसी तरह के एक विशाल सुधार प्रदान करेगा। क्या यह व्यवहार्य होगा? आप कुछ सेकंड में परिणाम देख सकते हैं।

mysql -e 'select search.* from search join contains using (keyword)' > outfile.txt 

# but first you need to create the tables like this (only once off) 

create table contains (
    keyword varchar(255) 
    , primary key (keyword) 
); 

create table search (
    keyword varchar(255) 
    ,num bigint 
    ,key (keyword) 
); 

# and load the data in: 

load data infile 'file.contain.query.txt' 
    into table contains fields terminated by "add column separator here"; 
load data infile 'file.to.search.in.txt' 
    into table search fields terminated by "add column separator here"; 
+0

मैंने इसका परीक्षण नहीं किया है, लेकिन यह आपकी स्थिति के आधार पर थोड़ा सा tweaking के साथ काम करेगा। जब तक आप इसे रैम आधारित नहीं करना चाहते हैं, तब तक यह बहुत कम स्मृति लेगा। –

0
use strict; 
use warings; 

system("sort file.contain.query.txt > qsorted.txt"); 
system("sort file.to.search.in.txt > dsorted.txt"); 

open (QFILE, "<qsorted.txt") or die(); 
open (DFILE, "<dsorted.txt") or die(); 


while (my $qline = <QFILE>) { 
    my ($queryid) = ($qline =~ /ENST(\d+)/); 
    while (my $dline = <DFILE>) { 
    my ($dataid) = ($dline =~ /ENST(\d+)/); 
    if ($dataid == $queryid) { print $qline; } 
    elsif ($dataid > $queryid) { break; } 
    } 
} 
6

आप तार तय कर दी है, तो grep -F -f का उपयोग करें। यह regex खोज से काफी तेज है।

5

तो फ़ाइलों को पहले से ही हल कर रहे हैं:

join file1 file2 

नहीं करता है, तो:

join <(sort file1) <(sort file2) 
4

आप पर्ल संस्करण 5.10 या नए, आप एक नियमित अभिव्यक्ति में 'जिज्ञासा' मामले में शामिल हो सकते उपयोग कर रहे हैं 'पाइप' से अलग क्वेरी शब्दों के साथ। (जैसे: ENST001|ENST002|ENST003) पर्ल एक 'ट्राई' बनाता है, जो हैश की तरह, निरंतर समय में लुकअप करता है। इसे लुकअप हैश का उपयोग करके समाधान के रूप में तेज़ी से चलाना चाहिए। ऐसा करने के लिए बस एक और तरीका दिखाने के लिए।

#!/usr/bin/perl 
use strict; 
use warnings; 
use Inline::Files; 

my $query = join "|", map {chomp; $_} <QUERY>; 

while (<RAW>) { 
    print if /^(?:$query)\s/; 
} 

__QUERY__ 
ENST001 
ENST002 
ENST003 
__RAW__ 
ENST001 90 
ENST002 80 
ENST004 50 
संबंधित मुद्दे