Bagaimana saya bisa menghitung jumlah baris dalam file setelah kecocokan grep?

14

Saya mencoba menghitung jumlah baris setelah baris bermasalah dalam file csv. Saya sadar saya bisa menggunakan grep -a #sintaks untuk menghasilkan # jumlah baris setelah kecocokan ditemukan. Saya hanya tertarik pada jumlah baris yang sebenarnya. Saya menyadari bahwa saya dapat mengatur nomor ke MAX_INT, pipa ke file dan melakukan pemrosesan lebih lanjut

Saya mencari kalimat singkat untuk memberi tahu saya hitungannya.

Ada saran?

NathanChristie
sumber

Jawaban:

15
{ grep -m1 match; grep -c ''; } <file

Itu akan bekerja dengan GNU grepdan lseek()infile yang dapat. Yang pertama grepakan berhenti pada 1 -match, dan yang kedua akan -cmenghantui setiap baris yang tersisa di input.

Tanpa GNU grep:

{ sed '/match/q'; grep -c ''; } <file

Tentu saja, dengan grepAnda dapat menggunakan semua / semua opsi lainnya selain, dan berhenti pada satu pertandingan sama sekali tidak diperlukan.

mikeserv
sumber
Keduanya juga mencetak baris, dan yang kedua pada cetakan hingga pertandingan pertama dan kemudian 0 untuk saya?
123
@ User112638726 - Anda dapat menjatuhkan cetakan pertandingan pertama dengan grep -m1 match >/dev/nulltentu saja. Dan masalah kedua Anda adalah GNU sed- tidak mereset input offsetnya per spec. Anda harus menggunakan -uw / GNU - yang tidak selalu diinginkan. Saya bisa lebih jelas, tetapi asumsi saya adalah bahwa GNU grepdan GNU sedakan berpasangan. Saya pikir, juga, grep -qm1bisa bekerja untuk jalan pintas /dev/nullredirect - tetapi GNU grepmelakukan hal-hal aneh w / -qdan saya tidak dapat mengingat bagaimana keduanya bekerja bersama.
mikeserv
1
Jawaban yang bagus - benar-benar menunjukkan kekuatan pengelompokan perintah. Saya tidak tahu pasti, tapi saya kira wc -lsedikit lebih murah daripada grep -c ''.
Trauma Digital
1
@DigitalTrauma - Ya, saya menganggapnya (dalam retrospeksi) , tapi saya sudah menulisnya, dan itu hampir berirama, jadi saya pikir saya akan cukup baik sendirian. Lagi pula, kamu mengatakannya juga, jadi aku akan tidur nyenyak sekarang.
mikeserv
9

Ini satu cara.

$ cat foo
aaa
bbb
ccc
ddd
eee
fff
$ awk '/^ddd/{a=FNR}END{print FNR-a}' foo
2
$
steve
sumber
4
ini bukan codegolf, bisakah Anda memberikan detail (FNR, END dan sebagainya)?
Archemar
3
Tentu. awk menggunakan FNR untuk mengidentifikasi nomor catatan input. END adalah kode yang dieksekusi saat mencapai akhir file. Jadi ketika kecocokan ditemukan, nomor rekaman saat ini dicatat. Saat mencapai akhir file, angka itu kemudian dikurangi dari jumlah total baris dalam file.
steve
1
Mungkin juga hanya menggunakan NR karena ini adalah satu file.
123
6

Cara lain - penggunaan dcsedikit esoteris, tetapi tampaknya bekerja dengan baik di sini:

sed -n '/problem/=;$=' prob.txt | dc -e '??r-p'

sedmencari prob.txt"masalah" dan baris terakhir, dan menggunakan =perintah untuk menampilkan nomor baris keduanya.

dc membaca dua nilai ini ke stack, membalikkannya, mengurangi dan mencetak perbedaannya.

Trauma Digital
sumber
5

Sepenuhnya dengan sed (meskipun dua perintah dengan pipa)

sed '/ddd/,$!d' file | sed -n '$='

Menghapus semua baris sebelum baris dan kemudian perintah selanjutnya menghitung baris dalam file baru.

123
sumber
3

Ini harus menghapus semua baris hingga (dan termasuk) yang bermasalah dan kemudian menghitung baris yang tersisa:

sed '1,/problem/d' data.txt | wc -l
tamu
sumber
1
(dengan asumsi "masalah" bukan pada baris pertama)
Stéphane Chazelas