Ters grepping


44

Diyelim ki gerçekten büyük bir metin dosyam var (yaklaşık 10.000.000 satır). grepSonundan bir dosyaya ihtiyacım var ve sonucu bir dosyaya kaydetmem gerekiyor. Görevi başarmanın en etkili yolu nedir?


10
İstediğinizi elde etmek için tacve grepdüğmelerini kullanın .
Valentin Bajrami

1
Yayınlanan mükemmel çözümlere ek olarak, GNU grep, --max-count (number)sizin için ilginç olabilecek belli sayıda maçtan sonra geri kalan bir düğmeye sahiptir .
Ulrich Schwarz

@ val0x00ff bu soruya bir göz atabilir misin
c0rp

Ne kadar vuruşun olacağını biliyor musun? Grep'inizin 3 çizgi bulacağını düşününce, grepping işlemine başlayın ve daha sonra geriye doğru gidin.
Walter 1

Yanıtlar:


46

tac / grep Çözümü

tac file | grep whatever

Ya da biraz daha etkili:

grep whatever < <(tac file)

500 MB dosya içeren zaman:

real    0m1.225s
user    0m1.164s
sys     0m0.516s

sed / grep Çözümü:

sed '1!G;h;$!d' | grep whatever

500 MB dosya içeren süre: 10+ dakika sonra iptal edildi.

awk / grep Çözüm:

awk '{x[NR]=$0}END{while (NR) print x[NR--]}' file | grep whatever

500 MB dosya içeren zaman:

real    0m5.626s
user    0m4.964s
sys     0m1.420s

perl / grep Çözümü:

perl -e 'print reverse <>' file | grep whatever

500 MB dosya içeren zaman:

real    0m3.551s
user    0m3.104s
sys     0m1.036s

2
sed, awkve perl(bu yöntem ile), dosyayı en başından okudukları için Tamam değil, bu da çok yetersiz. Sanırım bu tacdoğru olanı yapıyor.
vinc17

1
@ vinc17 evet, zaman istatistikleri söylediklerini gösteriyor.
kaos

2
@ val0x00ff < <(tac filename)Bir boru kadar hızlı olmalıdır: her iki durumda da komutlar paralel olarak çalışır.
vinc17

7
Verimlilik için gidiyorsanız, tacardı ardına koymak daha iyi olur . 10.000.000 satırlık bir dosyanız varsa, yalnızca 2 eşleşme tacvarsa, 10m değil, yalnızca 2 satır tersine çevirmeniz gerekir. grephala her şeyden bir şekilde geçmek zorunda kalacak.
Patrick,

3
tacSonra koyarsanız grep, bir borudan okuma olacak ve bu yüzden arayamaz. Bulunan satır sayısı büyükse bu daha az verimli (ya da tamamen başarısız) yapacaktır.
jjanes

17

Bu çözüm yardımcı olabilir:

tac file_name | grep -e expression

3
tacGNU komutudur. Diğer çoğu sistemde, eşdeğerdir tail -r.
Stéphane Chazelas

@ Stéphane: En azından bazı Unix sistemlerinde tail -raz sayıda çizgiyle sınırlıdır, bu bir sorun olabilir.
RedGrittyBrick

1
@RedGrittyBrick, bunun için herhangi bir referansınız var mı, yoksa lütfen hangi sistemlerin bu sınırlandırmaya sahip olduğunu söyleyebilir misiniz?
Stéphane Chazelas

@ StéphaneChazelas, ile tail -r /etc/passwdbaşarısız olur tail: invalid option -- 'r'. Coreutils-8.21-21.fc20.x86_64 kullanıyorum.
Cristian Ciupitu

@CristianCiupitu, dediğim gibi, GNU’nun tacdiğer birçok Unice’de (ve sadece GNU’nun tacı var) var tail -r. GNU taildesteklemiyor-r
Stéphane Chazelas

10

Bu, ilk eşleşmeyi bulur bulmaz çıkar:

 tac hugeproduction.log | grep -m1 WhatImLookingFor

Aşağıdaki ilk iki maçtan önce ve sonra 5 satır verir:

 tac hugeproduction.log | grep -m2 -A 5 -B 5 WhatImLookingFor

-iGrep'i yavaşlatacağınız sürece, (büyük / küçük harfe duyarsız) kullanmamanızı unutmayın .

Tam olarak aradığınız dizeyi biliyorsanız o zaman düşünün fgrep(Sabit Dize)

 tac hugeproduction.log | grep -F -m2 -A 5 -B 5 'ABC1234XYZ'

9

Eğer dosya gerçekten büyükse, belleğe sığamıyorsaPerl , File :: ReadBackwards modülü ile kullanacağım CPAN:

$ cat reverse-grep.pl
#!/usr/bin/perl

use strict;
use warnings;

use File::ReadBackwards;

my $pattern = shift;
my $rev = File::ReadBackwards->new(shift)
    or die "$!";

while (defined($_ = $rev->readline)) {
    print if /$pattern/;
}

$rev->close;

Sonra:

$ ./reverse-grep.pl pattern file

Bu yaklaşımın avantajı, istediğiniz her şeyi yapmak için Perl'i ince ayarlayabilmenizdir.
zzapper

1
@zzapper: Belleğe benzer bir slurp dosyası yerine satır satır dosya okuduğundan beri de bellek tasarrufu sağlar tac.
cuonglm

Herkes bunun için bir -m desteği ekleyebilir mi? Gerçek dosyalar üzerinde denemek istiyorum. Bakınız: gist.githubusercontent.com/ychaouche/…
ychaouche
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.