Grep kullanarak bir dosyadaki son eşleşmeyi elde etme


58

Grep kullanan bir dosyadaki normal ifadenin yalnızca son eşleşmesini elde etmenin en iyi yolu nedir?

Ayrıca, başlangıç ​​yerine dosyanın sonundan başlayarak greplemeye başlamak ve ilk eşleşmeyi bulduğunda durmak mümkün müdür?

Yanıtlar:


85

Deneyebilirsin

grep pattern file | tail -1

veya

tac file | grep pattern | head -1

veya

tac file | grep -m1 pattern

20
tac file | grep -m 1 pattern
Dennis Williamson,

1
Satır numarasını ( grep -n) asıl dosyaya almak istediğim eklenen kısıtlama ile, tacbazı çıkarma işlemleri yapmak istemediğim sürece, fazlasıyla kaçınılması gerektiğini düşünüyorum wc -l. Aksi tacile grep -m1anlamda bir çok yapar.
Nick Merrill,

1
20GB'lık bir dosyayı aramaya çalıştığım için bundan daha performanslı bir sürüm görmek isterim.
Jeff,

@DennisWilliamson'ın cevabı çok daha iyi çünkü grepilk maçtan sonra çalışmayı bırakacak. olmadan -m 1, grepönce dosyadaki tüm eşleşen kalıpları bulacak , sonra headsadece ilkini gösterecek - daha az verimli. Dennis, lütfen bunu ayrı bir cevapta göndermeyi düşün!
gilad mayani

1

Unix / Linux / Mac / Cygwin'deki büyük metin dosyalarıyla çalışan biri için. Windows kullanıyorsanız, Windows'taki Linux araçları hakkında bunu kontrol edin: https://stackoverflow.com/questions/3519738/what-is-the-best-way-to-use-linux-utilities-under-windows .

İyi bir performansa sahip olmak için bu iş akışını takip edebilirsiniz:

  1. gzip ile sıkıştır
  2. dosyayı uygun anahtarla indekslemek için zindex kullanın (github'da: https://github.com/mattgodbolt/zindex )
  3. Dizine zqalınmış dosyayı paketten sorgula .

Onun github benioku alıntı:

Dizin oluşturma

zindex'in, her satırın hangi bölümünün indeksi oluşturduğu söylenmelidir. Bu, düzenli bir ifadeyle, alana göre veya her bir satırı harici bir programdan geçirerek yapılabilir.

Varsayılan olarak zindex, file.gz dizinine girmeniz istendiğinde bir file.gz.zindex dizini oluşturur.

Örnek:

sayısal bir düzenli ifadeyle eşleşen satırlarda bir dizin oluşturun. Yakalama grubu, dizine alınacak kısmı belirtir ve seçenekler, her satırın benzersiz ve sayısal bir dizini olduğunu gösterir.

$ zindex file.gz --regex 'id:([0-9]+)' --numeric --unique

Örnek: CSV dosyasının ikinci alanında bir dizin oluşturun:

$ zindex file.gz --delimiter , --field 2 

Örnek:

JSON alanında orderId.id dizininde, belge kökünün actions dizisindeki öğelerin herhangi birinde (jq gerekir) dizin oluşturun. Jq sorgusu tüm orderId.ids dizisini oluşturur, ardından jq'ye aktarılan her bir hattın boşlukla ayrılmış (varsayılan ayırıcı olan) birden fazla eşleşmeyle tek bir çıktı satırı oluşturmasını sağlamak için onları bir boşlukla birleştirir.

$ zindex file.gz --pipe "jq --raw-output --unbuffered '[.actions[].orderId.id] | join(\" \")'" 

Dizini sorgulama

Zq programı bir dizini sorgulamak için kullanılır. Sıkıştırılmış dosyanın adı ve bir sorgu listesi verilmiştir. Örneğin:

$ zq file.gz 1023 4443 554 

Satır numarasına göre çıktı almak mümkündür, böylece 1 ve 1000 numaralı satırları bir dosyadan yazdırmak için:

$ zq file.gz --line 1 1000

1

Ben her zaman kedi kullanıyorum (ama bu biraz daha uzun sürüyor): cat file | grep pattern | tail -1

Kolejde linux admin kursu öğretmenimi suçlardım kedileri sever :))))

- Grep yapmadan önce bir dosyayı almak zorunda değilsiniz. grep pattern file | tail -1ve de daha verimlidir.


6
Bu, Cakemox'un cevabının sadece ilk kısmı, daha da kötüsü hariç.
ağustos

Çalışıyor, ancak gereksiz adımlar atıyor. Hafif kullanım için bu çözüm iyi çalışıyor, ancak iyi performans göstermiyor. Bunun nedeni, catdosyaya ve boruya gerek duymamanızdır grep. Sen olabilir grepdoğrudan aracılığıyla dosyayı arama grep pattern file(kullanmak sonra ve tailCakemox yanıtında olduğu gibi, son sonuç döndürmek için).
jvriesem
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.