Użyj grep, aby zgłosić tylko numery linii

106

Mam plik, który prawdopodobnie zawiera złe formatowanie (w tym przypadku wystąpienie wzorca \\backslash). Chciałbym użyć grepdo zwrócenia tylko numerów linii, w których to występuje (tak jak w przypadku, dopasowanie było tutaj, przejdź do linii # x i napraw to).

Jednak wydaje się, że nie ma sposobu na wydrukowanie numeru wiersza ( grep -n), a nie dopasowania lub samego wiersza.

Mogę użyć innego wyrażenia regularnego, aby wyodrębnić numery wierszy, ale chcę się upewnić, że grep nie może tego zrobić samodzielnie. grep -nowydaje mi się, że jest najbliżej, ale nadal wyświetla dopasowanie.

Neil
źródło
1
Najbardziej użyteczną dla mnie odpowiedzią było pytanie grep -no:! Zrobiłem to, co przyjechałem tutaj, aby spróbować! (tzn. nie drukuj linii, która jest czasami bardzo długa, np. zminimalizowane pliki źródłowe javascript.)
LondonRob

Odpowiedzi:

156

próbować:

grep -n "text to find" file.ext | cut -f1 -d:
love_me_some_linux
źródło
1
Na moim komputerze jest to tylko drukowanie dopasowanych plików bez numerów wierszy (więc jeśli mam 3 dopasowania w pliku, jest to drukowane tylko raz), co jest bardzo przydatne ...
Mario Awad
3
@MarioAwad, powinieneś manipulować -fparam. Dla mnie to było -f2. (Wiem, że to stare rzeczy, ale myślę, że mogłoby to pomóc niektórym biednym duszom)
Emil Sierżęga
dzięki za piękne, stare skrypty adhoc w unixie. pokazuje to, że elastyczne narzędzia są warte swojej złożoności i krzywej uczenia się!
Alex,
12
grep -n "text to find" file.ext | cut -f1,2 -d:pokazuje nazwę pliku i numer linii.
Jondlm
2
@jondim pokazuje nazwę pliku tylko wtedy, gdy przeszukiwany jest więcej niż jeden plik; musisz dodać, -Haby wymusić wyświetlenie nazwy pliku, gdy jest tylko jeden plik. I odwrotnie, zawsze możesz użyć polecenia, -haby nie wyprowadzać nazwy pliku, bez względu na to, ile plików grepujesz.
Mark Reed,
45

Jeśli jesteś otwarty na używanie AWK:

awk '/textstring/ {print FNR}' textfile

W tym przypadku FNR to numer linii. AWK to świetne narzędzie, gdy patrzysz na grep | cut lub gdy chcesz pobrać wyjście grep i manipulować nim.

Brightlancer
źródło
2
Używa jednego procesu (który miał większe znaczenie w przeszłości, ale nadal) i jest wystarczająco łatwy do zrozumienia dla początkujących użytkowników awk!
bgStack15
NRdziała również wtedy, gdy badany jest tylko jeden plik, jak w tym przypadku.
Mark Reed
Po prostu genialne! To jest takie szybkie!
GTodorov
34

Wszystkie te odpowiedzi wymagają, aby grep wygenerował całe pasujące wiersze, a następnie przesłał je do innego programu. Jeśli twoje linie są bardzo długie, może być bardziej efektywne użycie seda do wyświetlenia numerów linii:

sed -n '/pattern/=' filename
politycznie niezależny
źródło
2

Wersja Bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}
politycznie niezależny
źródło
1
A co się stanie, jeśli więcej niż jedna linia pasuje do tego wzorca?
izabera
@izabera dodaj | ogon -1
Diego
1

Polecam odpowiedź z sedi awkdo dopiero się numer linii, zamiast grepdostać całą linię dopasowania i następnie usunięcie że od wyjścia z cutlub innego narzędzia. Aby uzyskać kompletność, możesz również użyć Perla:

perl -nE '/pattern/ && say $.' filename

lub Ruby:

ruby -ne 'puts $. if /pattern/' filename
Mark Reed
źródło
0

Będziesz potrzebował drugiego pola po dwukropku, a nie pierwszego.

grep -n "text to find" file.txt | cut -f2 -d:

Chris
źródło
Działa to, jeśli chcesz dopasować tekst, ale w przypadku, gdy numer linii jest tym, o co prosił OP.
AJP
0

Aby policzyć liczbę wierszy pasujących do wzorca:

grep -n "Pattern" in_file.ext | wc -l 

Aby wyodrębnić dopasowany wzór

sed -n '/pattern/p' file.est

Aby wyświetlić numery wierszy, do których dopasowano wzór

grep -n "pattern" file.ext | cut -f1 -d:
JstRoRR
źródło
2
Najpierw powinno być „grep -c 'Wzorzec' in_file.ext”. Drugą pozycją powinno być „grep -o 'Pattern' in_file.ext”. Nie ma potrzeby angażowania sed lub wc.
thelogix
0

używając tylko grepa :

grep -n "text to find" file.ext | grep -Po '^[^:]+'

Micael Levi
źródło