Abrufen der letzten Übereinstimmung in einer Datei mit grep

58

Was ist der beste Weg, um mit grep nur die endgültige Übereinstimmung eines regulären Ausdrucks in einer Datei zu erhalten?

Ist es auch möglich, am Ende der Datei statt am Anfang mit dem Greifen zu beginnen und zu stoppen, wenn die erste Übereinstimmung gefunden wird?

Eichel
quelle

Antworten:

85

Du könntest es versuchen

grep pattern file | tail -1

oder

tac file | grep pattern | head -1

oder

tac file | grep -m1 pattern
Cakemox
quelle
20
tac file | grep -m 1 pattern
Dennis Williamson
1
Mit der zusätzlichen Einschränkung, dass ich die Zeilennummer ( grep -n) in der eigentlichen Datei haben wollte, musste ich meiner Meinung nach tacziemlich viel vermeiden, es sei denn, ich wollte etwas subtrahieren wc -l. Ansonsten tacmit grep -m1macht sehr viel Sinn.
Nick Merrill
1
Ich würde gerne eine performantere Version sehen, da ich versuche, eine 20-GB-Datei zu durchsuchen.
Jeff
@DennisWilliamsons Antwort ist viel besser, weil grepsie nach dem ersten Spiel nicht mehr funktioniert. without -m 1, grepfindet zuerst alle passenden Muster in der Datei und zeigt dann headnur das erste an - viel weniger effizient. Dennis, bitte schreibe dies in eine separate Antwort!
Gilad Mayani
1

Für jemanden, der mit riesigen Textdateien unter Unix / Linux / Mac / Cygwin arbeitet. Wenn Sie Windows verwenden, informieren Sie sich über Linux-Tools in Windows: https://stackoverflow.com/questions/3519738/what-is-the-best-way-to-use-linux-utilities-under-windows .

Man kann diesem Workflow folgen, um eine gute Leistung zu erzielen:

  1. Mit gzip komprimieren
  2. Verwenden Sie zindex (auf github: https://github.com/mattgodbolt/zindex ), um die Datei mit dem entsprechenden Schlüssel zu indizieren
  3. Fragen Sie die indizierte Datei mit zqaus dem Paket ab.

Zitat aus seiner Github Readme:

Index erstellen

zindex muss mitgeteilt werden, welcher Teil jeder Zeile den Index bildet. Dies kann durch einen regulären Ausdruck, durch ein Feld oder durch Weiterleiten jeder Zeile durch ein externes Programm erfolgen.

Standardmäßig erstellt zindex einen Index von file.gz.zindex, wenn Sie aufgefordert werden, file.gz zu indizieren.

Beispiel:

Erstellen Sie einen Index für Zeilen, die einem numerischen regulären Ausdruck entsprechen. Die Erfassungsgruppe gibt den Teil an, der indiziert werden soll, und die Optionen zeigen, dass jede Zeile einen eindeutigen numerischen Index hat.

$ zindex file.gz --regex 'id:([0-9]+)' --numeric --unique

Beispiel: Erstellen Sie einen Index für das zweite Feld einer CSV-Datei:

$ zindex file.gz --delimiter , --field 2 

Beispiel:

Erstellen Sie einen Index für ein JSON-Feld orderId.id in einem der Elemente im Actions-Array des Dokumentstamms (erfordert jq). Die jq-Abfrage erstellt ein Array aller orderId.ids und fügt ihnen dann ein Leerzeichen hinzu, um sicherzustellen, dass jede einzelne an jq weitergeleitete Zeile eine einzelne Ausgabezeile mit mehreren Übereinstimmungen erstellt, die durch Leerzeichen getrennt sind (dies ist das Standardtrennzeichen).

$ zindex file.gz --pipe "jq --raw-output --unbuffered '[.actions[].orderId.id] | join(\" \")'" 

Index abfragen

Mit dem Programm zq wird ein Index abgefragt. Es wird der Name der komprimierten Datei und eine Liste von Abfragen angegeben. Zum Beispiel:

$ zq file.gz 1023 4443 554 

Es ist auch möglich, nach Zeilennummer auszugeben, um die Zeilen 1 und 1000 aus einer Datei zu drucken:

$ zq file.gz --line 1 1000
Biocyberman
quelle
1

Ich benutze immer Katze (aber das macht es ein bisschen länger): cat file | grep pattern | tail -1

Ich würde meinen Linux Admin Kurslehrer am College beschuldigen, der Katzen liebt :))))

- Sie müssen eine Datei nicht erst kategorisieren, bevor Sie sie greifen können. grep pattern file | tail -1und ist auch effizienter.

Ismail Guneydas
quelle
6
Dies ist nur der erste Teil von Cakemox 'Antwort, außer schlimmer.
15.
Es funktioniert, aber es macht unnötige Schritte. Für den leichten Gebrauch funktioniert diese Lösung gut, funktioniert aber nicht gut. Der Grund dafür ist, dass Sie catdie Datei nicht brauchen, um sie weiterzuleiten grep. Sie können grepdie Datei direkt über durchsuchen grep pattern file(und dann verwenden tail, um das letzte Ergebnis zurückzugeben), wie in der Antwort von Cakemox.
Jvriesem