Verwenden Sie grep, um nur Zeilennummern zu melden

105

Ich habe eine Datei, die möglicherweise eine schlechte Formatierung enthält (in diesem Fall das Auftreten des Musters \\backslash). Ich möchte verwenden grep, um nur die Zeilennummern zurückzugeben, in denen dies auftritt (wie in, die Übereinstimmung war hier, gehen Sie zu Zeile # x und korrigieren Sie sie).

Es scheint jedoch keine Möglichkeit zu geben, die Zeilennummer ( grep -n) und nicht die Übereinstimmung oder Zeile selbst zu drucken .

Ich kann einen anderen regulären Ausdruck verwenden, um die Zeilennummern zu extrahieren, aber ich möchte sicherstellen, dass grep dies nicht alleine tun kann. grep -nokommt am nächsten, denke ich, zeigt aber immer noch die Übereinstimmung.

Neil
quelle
1
Die nützlichste Antwort für mich war die Frage : grep -no! Dies tat, was ich hierher kam, um zu versuchen und zu tun! (dh nicht die Zeile drucken, die manchmal sehr lang ist, z. B. in minimierten Javascript-Quelldateien.)
LondonRob

Antworten:

155

Versuchen:

grep -n "text to find" file.ext | cut -f1 -d:
love_me_some_linux
quelle
1
Auf meinem Computer werden nur die übereinstimmenden Dateien ohne Zeilennummern gedruckt (wenn ich also 3 Übereinstimmungen in einer Datei habe, wird diese nur einmal gedruckt), was immer noch sehr nützlich ist ...
Mario Awad
3
@MarioAwad, du solltest -fparam manipulieren . Für mich war es -f2. (Wissen Sie, dass dies altes Zeug ist, aber ich denke, es könnte einigen armen Seelen helfen)
Emil Sierżęga
Vielen Dank für das schöne alte Unix-Ad-hoc-Shell-Scripting. Dies zeigt, dass flexible Tools ihre Komplexität und Lernkurve wert sind!
Alex
12
grep -n "text to find" file.ext | cut -f1,2 -d:zeigt den Dateinamen und die Zeilennummer.
Jondlm
2
@jondim zeigt den Dateinamen nur an, wenn mehr als eine Datei durchsucht wird; Sie müssen hinzufügen, um -Hzu erzwingen, dass der Dateiname angezeigt wird, wenn nur eine Datei vorhanden ist. Umgekehrt können Sie immer -hangeben, dass der Dateiname nicht ausgegeben werden soll, unabhängig davon, wie viele Dateien Sie erfassen.
Mark Reed
45

Wenn Sie offen für die Verwendung von AWK sind:

awk '/textstring/ {print FNR}' textfile

In diesem Fall ist FNR die Zeilennummer. AWK ist ein großartiges Tool, wenn Sie sich grep | cut ansehen oder wenn Sie eine grep-Ausgabe nehmen und bearbeiten möchten.

Brightlancer
quelle
2
Verwendet einen Prozess (der in der Vergangenheit wichtiger war, aber immer noch) und für awk-Anfänger leicht zu verstehen ist!
bgStack15
NRfunktioniert auch, wenn nur eine Datei untersucht wird, wie in diesem Fall.
Mark Reed
Einfach genial! Es ist so schnell!
GTodorov
34

Für all diese Antworten muss grep die gesamten übereinstimmenden Zeilen generieren und dann an ein anderes Programm weiterleiten. Wenn Ihre Zeilen sehr lang sind, ist es möglicherweise effizienter, nur sed zur Ausgabe der Zeilennummern zu verwenden:

sed -n '/pattern/=' filename
Einzelgänger
quelle
2

Bash-Version

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}
Einzelgänger
quelle
1
Und was passiert, wenn mehr als eine Zeile diesem Muster entspricht?
Izabera
@izabera hinzufügen | Schwanz -1
Diego
1

Ich empfehle die Antworten mit sedund awknur zum Abrufen der Zeilennummer, anstatt grepdie gesamte übereinstimmende Zeile abzurufen und diese dann mit cuteinem anderen Tool aus der Ausgabe zu entfernen . Der Vollständigkeit halber können Sie auch Perl verwenden:

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

oder Ruby:

ruby -ne 'puts $. if /pattern/' filename
Mark Reed
quelle
0

Sie wollen das zweite Feld nach dem Doppelpunkt, nicht das erste.

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

Chris
quelle
Dies funktioniert, wenn Sie Text abgleichen möchten, aber in dem Fall ist die Zeilennummer das, wonach das OP gefragt hat.
AJP
0

So zählen Sie die Anzahl der Zeilen, die dem Muster entsprechen:

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

Übereinstimmendes Muster extrahieren

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

Anzeigen von Zeilennummern, auf denen das Muster übereinstimmte

grep -n "pattern" file.ext | cut -f1 -d:
JstRoRR
quelle
2
1. sollte nur "grep -c 'Pattern' in_file.ext" sein. 2. sollte "grep -o 'Pattern' in_file.ext" sein. Keine Notwendigkeit, sed oder wc einzubeziehen.
Thelogix
0

mit nur grep :

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

Micael Levi
quelle