Sadece ilk maçı aç ve durdur


329

Ben sadece ilk eşleşme dönmek umuduyla aşağıdaki argümanlar ile grep kullanarak özyineli bir dizin arıyorum. Ne yazık ki, birden fazla döndü - aslında son baktığımda iki. Görünüşe göre çok fazla argümanım var, özellikle de istenen sonucu almadan. : - /

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory

İadeler:

Pulsanti Operietur
Pulsanti Operietur

Belki grep bunu yapmanın en iyi yolu değildir? Bana söyle, çok teşekkürler.

Yanıtlar:


512

-m 1herhangi bir dosyadaki ilk eşleşmeyi döndürmek anlamına gelir. Ancak yine de başka dosyalarda arama yapmaya devam edecektir. Ayrıca, aynı satırda iki veya daha fazla eşleşen varsa, hepsi görüntülenir.

head -1Bu sorunu çözmek için kullanabilirsiniz :

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1

her grep seçeneğinin açıklaması:

-o, --only-matching, print only the matched part of the line (instead of the entire line)
-a, --text, process a binary file as if it were text
-m 1, --max-count, stop reading a file after 1 matching line
-h, --no-filename, suppress the prefixing of file names on output
-r, --recursive, read all files under a directory recursively

müthiş! teşekkür ederim. btw - komutta sahip olduğum diğer tüm argümanlar gerekli mi? ve eğer şans eseri borulayamazsam (ne olur ne olmaz).
Tim Kamm

2
Ben gerekli olduğunu düşünmüyorum ( -rtabii ki hariç ), ama onlar incitmemeli (Ben de kullanmazdım -a)
mvp

3
Tam olarak ihtiyacım olan şey. Desenim aynı satırda iki kez bulundu ve grep -m 1bu nedenle her iki örneği de döndürdü. |head -1çözüldü!
harperville

6
@Chris_Rands tam davranış içinde çalıştığınız kabuk bağlıdır. Head ilk satır karşılaşır karşılaşmaz çıkacaktır. grep, kafa çıktıktan sonra bir sonraki yazmaya çalıştığında kapanacaktır. Bazı mermiler bir boru hattının tüm unsurları bitene kadar bekleyecek, bazıları da borudaki son program çıkar çıkmaz tüm borunun kapanmasına neden olacaktır.
puhlen

1
3QN @, senin yorumunu anlamıyorum: first not first from result. Bu yanıt ilk olarak herhangi bir dosyada eşleşir ve durur. Başka ne bekliyordun?
mvp

31

Sen boru can grepsonucu headile birlikte stdbuf .

N'inci eşleşmeden sonra durmayı sağlamak için çıktısını arabelleğe almadığınızdan stdbufemin olmak için kullanmanız grepgerektiğini unutmayın:

stdbuf -oL grep -rl 'pattern' * | head -n1
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1
stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1

En kısa sürede headtükettiğini 1 hattı, bu sonlandırılmış ve grepalacak SIGPIPEboru süre için hala bir çıktı üretir çünkü headgitmişti.

Bu, hiçbir dosya adının satırsonu içermediğini varsaymıştır.


Birlikte arşiv dosyalarının çok sayıda arama yapmak için bu çözüm benimsemeye çalışıyorum xargs: find . -name '*.gz' | xargs -I '{}' stdbuf -oL zgrep -al 'pattern' {} | head -n 1. Ancak bu ilk maçta sona ermez. Herhangi bir tavsiye?
DKroot

1
Olmaz grep'ın --line-bufferedseçeneği ek bir yarar uğramadan havai tampon önlemek?
David

23

Grep-a-like programımın ackherhangi bir -1yerde bulunan ilk maçta durma seçeneği var. -m 1@Mvp'nin de ifade ettiği şeyi destekler . Oraya koydum çünkü tek bir dosyada var olduğunu bildiğim bir şey bulmak için büyük bir kaynak kodu ağacı ararsam, onu bulmak gereksizdir ve Ctrl-C'ye basmak zorunda kalmazsınız.


yani ack'ın grep'ten daha hızlı olduğunu söyleyebilir misiniz? Hız faktörü ile de gerçekten ilgileniyorum.
Tim Kamm

1
ack, aradığınız şeye bağlı olarak grep'ten daha hızlı olabilir. Lütfen ack'un kaynak kodu aramakla ilgili olduğunu unutmayın. Genel dosyaları aramak istiyorsanız, en azından ax 1.x'te daha az iyidir. Ack hakkında okuyun ve belki de ihtiyaçlarınıza uygun olup olmadığını görün.
Andy Lester

2
Ack'i

Bunun tek cevap olması gerektiğine inanıyorum, çünkü OP onun grep ile yapılmasını istediğini söyledi, ancak diğer cevap kafa kullanıyor (elbette her ikisi de iş) ama grep'in ortak ve kuyruk / kafa değil.
Areeb Soo Yasir

Worth söz aghızlı olabilir, ama bu değil sahip -1bu durumda yararlıdır seçeneği
JJA

4

Bulunduğunuz dizinde belirli bir sözcüğün oluşması durumunda tüm satırı ve dosya adını yazdırmak istiyorsanız aşağıdaki komutu kullanabilirsiniz.

grep -m 1 -r "Not caching" * | head -1

2

Kullanan tek bir astar find:

find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit

6
Bulma, bulunan her dosya için grep'in kopyasını üreteceğinden, bu çok yavaş olacaktır. grep -rçok daha hızlı çalışır - dizin geçişlerini yapan tek bir kopyası.
mvp

Doğru; ancak find yalnızca filtrelenmiş sonuçlar üzerinde çalışacak şekilde özelleştirilebilir ve bu da işlemi bir tümünü yakalama grepinden çok daha hızlı hale getirebilir. Bağlama bağlıdır.
Yam Marcovic
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.