Grep: hitung jumlah kecocokan per baris

26

Saya mencoba untuk mendapatkan jumlah kecocokan (dalam hal ini kejadian {atau }) di setiap baris file .tex.

Saya tahu bahwa -obendera hanya mengembalikan kecocokan, tetapi mengembalikan setiap kecocokan pada baris baru, bahkan dikombinasikan dengan -nbendera. Saya tidak tahu apa-apa saya bisa menyalurkan ini untuk menghitung pengulangan. The -cbendera hanya mengembalikan jumlah pertandingan di seluruh file - mungkin aku bisa pipa satu baris pada suatu waktu untuk grep?

Chris H.
sumber

Jawaban:

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

Outputnya akan seperti:

3 1
1 2

Berarti 3 kejadian di baris pertama dan 1 di baris kedua.

Diambil dari https://stackoverflow.com/a/15366097/3378354 .

Moebius
sumber
Terima kasih - google menemukan banyak hits regex di SU, tetapi tidak yang di SO, yang bahkan tampaknya tidak memiliki tag regex. Ini sorttidak sepenuhnya diperlukan karena output grep diurutkan berdasarkan nomor baris, tapi saya kira itu praktik yang baik sebelumnya uniq.
Chris H
2
Mungkin tidak ditandai regexkarena regex adalah bagian yang mudah.
Tom Zych
Apakah itu perlu sort -n? Bukankah itu keluar dalam urutan nomor baris?
Tom Zych
Anda benar, sort -ntidak perlu. Terima kasih.
Moebius
@ TomZych, ternyata Anda benar, tetapi seandainya saya tahu bahwa saya mungkin tidak bertanya. Lompatan mental dari grep ke tag: regex mungkin agak terlalu banyak.
Chris H
3

Setelah membaca berbagai solusi, saya pikir ini adalah pendekatan termudah untuk masalah:

while read i; do echo $i |grep -o "matchingString"| wc -l;  done < input.txt
alfredocambera
sumber
3
Solusi terbaik, menurut saya. Bisa lebih disederhanakan dengan mengurangi oleh salah satu pipa: grep -o "matchingString" <<< $i | wc -l.
Benjamin W.
1
Ini akan menjadi perintah yang besarnya lebih lambat daripada opsi lain
Rahul
1

Apakah menggunakan greppersyaratan? Inilah alternatifnya:

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

The sedstrip semua karakter selain {dan } (yaitu, hanya menyisakan {dan }karakter), dan kemudian awkjumlah karakter di setiap baris (yang hanya {dan }karakter). Untuk menekan garis tanpa kecocokan,

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

Perhatikan bahwa solusi saya mengasumsikan (mengharuskan) bahwa string yang Anda cari adalah karakter tunggal. Jawaban Moebius lebih mudah disesuaikan dengan string multi-karakter. Juga, tidak satu pun dari jawaban kami yang mengecualikan kemunculan karakter / rangkaian minat; misalnya,

{ "nullfunc() {}" }

akan dianggap mengandung empat karakter penjepit.

Scott
sumber
greptidak benar-benar persyaratan, itu hanya di mana saya mulai mencari solusi, karena itu memberi saya sesuatu yang dekat. Saya tidak pernah membutuhkan awk, jadi seandainya saya tidak menggunakan jawaban di atas, saya akan menggunakan ini sebagai kesempatan untuk bereksperimen - saya mungkin masih. Apa yang saya gagal jelaskan (tetapi tidak mempengaruhi jawaban mana pun) adalah bahwa saya ingin menjalankan skrip sekali per braket, untuk membantu saya melacak ketidakcocokan (dalam sumber LaTeX, di sini untuk tabel) di mana sebagian besar pasangan terjadi di satu baris.
Chris H
Saya tidak yakin apa yang Anda maksud dengan "menjalankan skrip sekali per braket," tetapi jika Anda ingin melacak ketidakcocokan penjepit, Anda mungkin ingin mencoba sesuatu seperti sed 's/{[^{}]*}//g' your_file | grep –n '[{}]', di mana sedstrip keluar (cocok) berpasangan. Jika Anda memiliki pasangan bersarang, gunakan sed 's/{[^{}]*}//g;s/{[^{}]*}//g;s/{[^{}]*}//g;…' …, ulangi s/{[^{}]*}//gsebanyak yang Anda miliki .
Scott
Maksud saya jalankan `sed 's / [^}] // g' your_file | awk '{print NR, length}' dan 's / [^ {] // g' your_file | awk '{print NR, length}'. Aku memang punya sarang, dan berolahraga di tingkat terdalam seperti tugas. Mengubah banyak baris menjadi beberapa (ada beberapa kasus di mana kawat hanya cocok dengan beberapa baris untuk alasan yang valid) bekerja dengan baik (saya menggunakan jedit yang menyoroti braket yang cocok - untuk semua jenis braket yang dimengerti - jadi saya benar-benar melakukannya hanya perlu mempersempitnya).
Chris H