Jak mogę policzyć liczbę linii w pliku po dopasowaniu grep?


14

Próbuję policzyć liczbę wierszy po problematycznym wierszu w pliku csv. Wiem, że mogę użyć grep -a #składni do wypisania # liczby wierszy po znalezieniu dopasowania. Interesuje mnie tylko faktyczna liczba linii. Zdaję sobie sprawę, że mogę ustawić liczbę na MAX_INT, przesłać ją do pliku i wykonać trochę więcej przetwarzania.

Szukam zwięzłego jedno-linijki, która powie mi tylko liczbę.

Jakieś sugestie?

Odpowiedzi:


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

To zadziała z GNU grepi lseek()zdolnym infile. Pierwszy grepzatrzyma się na 1 -mcal, a drugi -cpoliczy każdą linię pozostałą na wejściu.

Bez GNU grep:

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

Oczywiście, w / grepmożesz użyć dowolnej / wszystkich innych opcji poza tym, a zatrzymanie się przy jednym meczu nie jest wcale konieczne.


Oba drukują również linię, a druga na drukuje do pierwszego dopasowania, a następnie 0 dla mnie?
123,

@ User112638726 - możesz oczywiście upuścić wydruk pierwszego meczu grep -m1 match >/dev/null. Twoim drugim problemem jest GNU sed- nie resetuje on swojego przesunięcia wejściowego na specyfikację. Musisz używać -uw / GNU - co nie zawsze jest pożądane. Mógłbym być jaśniejszy, ale moje założenie było takie, że GNU grepi GNU sedprzyjdą w parach. Wydaje mi się, że można również grep -qm1skrócić /dev/nullprzekierowanie - ale GNU greprobi dziwne rzeczy w / -qi nie mogę sobie przypomnieć, jak te dwie rzeczy działają razem.
mikeserv

1
Dobra odpowiedź - naprawdę pokazuje siłę grup dowodzenia. Nie wiem na pewno, ale zgaduję, że wc -ljest trochę tańszy niż grep -c ''.
Digital Trauma

1
@DigitalTrauma - Tak, zastanowiłem się nad tym (z perspektywy czasu) , ale już to napisałem i prawie rymowałem, więc pomyślałem, że wystarczająco dobrze zostawiłem sobie w spokoju. Zresztą też to powiedziałeś, więc będę spał spokojnie.
mikeserv

9

Oto jeden sposób.

$ cat foo
aaa
bbb
ccc
ddd
eee
fff
$ awk '/^ddd/{a=FNR}END{print FNR-a}' foo
2
$

4
to nie jest codegolf, czy możesz podać szczegóły (FNR, END itd.)?
Archemar,

3
Pewnie. awk używa FNR do identyfikacji numeru rekordu wejściowego. END to kod wykonywany po osiągnięciu końca pliku. Kiedy więc zostanie znalezione dopasowanie, zapisywany jest bieżący numer rekordu. Po osiągnięciu końca pliku liczba ta jest następnie odejmowana od całkowitej liczby wierszy w pliku.
steve

1
Może również użyć NR, ponieważ jest to jeden plik.
123,

6

Innym sposobem - użycie dcjest trochę ezoteryczne, ale wydaje się, że działa tutaj ładnie:

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

sedwyszukuje prob.txt„problem” i ostatni wiersz i używa =polecenia, aby wyświetlić numer wiersza obu.

dc odczytuje te dwie wartości na stosie, odwraca je, odejmuje i drukuje różnicę.


5

Całkowicie za pomocą sed (choć dwa polecenia z potokiem)

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

Usuwa całą linię przed linią, a następnie następne polecenie zlicza linie w nowym pliku.


3

Powinno to usunąć wszystkie wiersze, aż do problematycznego, a następnie policzyć pozostałe wiersze:

sed '1,/problem/d' data.txt | wc -l

1
(zakładając, że „problem” nie występuje w pierwszej linii)
Stéphane Chazelas,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.