Grep: Her satıra düşen maç sayısı


26

Bir .tex dosyasının her satırındaki eşleşme sayısını (bu durumda {veya oluşumunu }) almaya çalışıyorum .

-oBayrağın yalnızca eşleşmeyi döndürdüğünü biliyorum , ancak her eşleşmeyi yeni bir satırda, hatta bayrağa bağlı olarak döndürdüğünü biliyorum -n. Tekrarları saymak için bunu aktarabileceğim bir şey bilmiyorum. -cBayrak sadece tüm dosyadaki toplam eşleşme sayısını döndürür - belki bir anda boru bir satır grep olabilir?

Yanıtlar:


27
grep -o -n '[{}]' <filename> | cut -d : -f 1 | uniq -c

Çıktı şöyle bir şey olacak:

3 1
1 2

İlk satırda 3 oluşum, ikinci sırada 1 olay.

Alındığı /programming//a/15366097/3378354 .


Teşekkürler - google SU’da çok sayıda regex isabeti buldu, ancak SO’da da bir regex etiketi yok gibi görünüyor. sortGrep çıkış hattı sayısına göre sıralanır olarak kesinlikle gerekli değildir, ama önce iyi bir uygulama olduğunu tahmin uniq.
Chris H,

2
Muhtemelen etiketlenmemiş regexçünkü regex kolay kısmı.
Tom Zych,

Aslında gerekli sort -nmi? Zaten sıra numarasıyla çıkmıyor mu?
Tom Zych

Haklısın, sort -ngerekli değil. Teşekkürler.
Moebius

@TomZych, haklı çıktı, ama sormadığımı biliyor muydum. Grep'ten tag'e zihinsel sıçrama: regex belki de biraz fazla oldu.
Chris H,

3

Çeşitli çözümleri okuduktan sonra, bunun soruna en kolay yaklaşım olduğunu düşünüyorum:

while read i; do echo $i |grep -o "matchingString"| wc -l;  done < input.txt

3
Bence en iyi çözüm. Daha da bir boru ile azaltılması basitleşeceğini Could: grep -o "matchingString" <<< $i | wc -l.
Benjamin W.

1
Bu daha sonra diğer seçeneklerden daha yavaş bir büyüklük emri olacak
Rahul

1

grepBir gereksinim kullanıyor mu? İşte bir alternatif:

sed 's / [^ {}] // g' your_file | awk '{print NR, uzunluk}'

sedDışındaki tüm karakterler dışarı şeritler {ve } (yani sadece bırakarak {ve }daha sonra karakter) ve awk(sadece her biri on line olarak sayar karakterler {ve }karakter). Eşleşmeyen satırları gizlemek için,

sed 's / [^ {}] // g' your_file | awk '/./ {baskı NR, uzunluk}'

Çözümümün, aradığınız dizgelerin tek karakter olduğunu varsaydığını (gerektirdiğini) unutmayın. Moebius'un cevabı çok karakterli dizgelere daha kolay uyarlanır. Ayrıca, cevaplarımızdan hiçbiri, ilgi çeken karakterlerin / karakterlerin alıntılanan veya çıkarılan olaylarını içermez; Örneğin,

{ "nullfunc() {}" }

dört ayraç karakter içerdiği kabul edilir.


grepgerçekten bir gereklilik değildi, sadece bir çözüm aramaya başladığım yerdi, çünkü bana yakın bir şey verdi. Awk için hiç ihtiyacım olmadı, bu yüzden yukarıdaki cevabı kullanmasaydım, bunu deneme şansı olarak kullanırdım - yine de olabilir. Netleştiremediğim (ancak her iki cevabı da etkilemeyen) senaryoyu her ayraçta bir kez çalıştırmak, çoğu eşleşmenin gerçekleştiği bir uyumsuzluğu (LaTeX kaynağında, burada bir tablo için) izlememe yardım etmek istediğimdir. tek bir çizgi.
Chris H,

“Senaryoyu her basamağa bir kez çalıştır” derken ne demek istediğinizi tam olarak bilmiyorum, ancak bir ayraç uyuşmazlığını izlemek istiyorsanız sed 's/{[^{}]*}//g' your_file | grep –n '[{}]', sedşeritlerin çiftleştiği (eşleşen) çiftler gibi bir şey denemek isteyebilirsiniz . Yuvalanmış çiftleriniz varsa , en derin yuvalamanızın kadar sed 's/{[^{}]*}//g;s/{[^{}]*}//g;s/{[^{}]*}//g;…' …tekrarlayarak kullanın s/{[^{}]*}//g.
Scott

'Sed' s / [^}] // g 'komutunu çalıştırmak istedim. Your_file | awk '{print NR, uzunluk}' ve 's / [^ {] // g' your_file | awk '{baskı NR, uzunluk}'. Gerçekten de yuvalarım var ve en derin seviyeye çalışmak bir angarya gibiydi. Birçok çizgiyi bir avuç içine çevirmek (parantezlerin geçerli nedenlerle yalnızca birden fazla çizgide eşleştiği birkaç durum vardır) iyi çalıştı (eşleşen braketi vurgulayan jedit kullanıyorum - anladığı herhangi bir braket türü için - bu yüzden gerçekten yaptım) sadece daraltmak gerekir).
Chris H,
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.