Wie kann man grep nur dann übereinstimmen lassen, wenn die gesamte Zeile übereinstimmt?


101

Ich habe diese:

$ cat a.tmp
ABB.log
ABB.log.122
ABB.log.123

Ich wollte eine genaue Übereinstimmung von ABB.log finden.

Aber als ich es tat

$ grep -w ABB.log a.tmp
ABB.log
ABB.log.122
ABB.log.123

es zeigt sie alle.

Kann ich mit grep bekommen, was ich wollte?

Antworten:


105

Geben Sie einfach die regulären Ausdrucksanker an.

grep '^ABB\.log$' a.tmp

2
Beide Anker (^ und $) werden benötigt.
user562374

2
Schön! Und wenn ich den regulären Ausdruck für den Abgleich aus einer Datei verwende? "grep -f Muster a.tmp" ??
grün69

@ green69 Einige Jahre zu spät, aber Sie können sed verwenden, um die Anker hinzuzufügen, bevor Sie die Muster an grep übergeben:sed -r "s/^(.*)$/^\1$/" patterns.txt | egrep -f - a.tmp
Randoms

153
grep -Fx ABB.log a.tmp

Von der grep-Manpage:

-F, --fixed-strings
Interpretieren Sie PATTERN als (Liste) fester Zeichenfolgen
-x, --line-regexp
Wählen Sie nur die Übereinstimmungen aus, die genau mit der gesamten Zeile übereinstimmen.


2
konnte -F leider nicht benutzen.
Johnyy

@ Johnyy Nein -F? Sind Sie auf Solaris? Wenn ja, verwenden Sie/usr/xpg4/bin/grep
Scrutinizer

9
Ich verwende grepin einem Bash-Skript und diese Option ist besser als die Verwendung eines regulären Ausdrucks, wie in der akzeptierten Antwort vorgeschlagen. Da die Variable, nach der ich suche (wie .), ein Sonderzeichen enthält, muss ich sie bei Verwendung des Befehls nicht umgehen.
Gustavo Straube

1
beste Antwort IMO, weil es Sonderzeichen erlaubt, ohne zu entkommen
ReneGAED

1
Dies ist besser, da es auch mit Variablen funktioniert.
Ybenjira

23

Folgendes mache ich, obwohl die Verwendung von Ankern der beste Weg ist:

grep -w "ABB.log " a.tmp

Wie dieses .. es wird First Line Match zurückgeben
user765443

Dies erfordert ein Leerzeichen danach ABB.log, was nicht der allgemeine Fall ist, dh es wird die meiste Zeit fehlschlagen.
Jahid

3

Die meisten Vorschläge schlagen fehl, wenn nur ein einziger führender oder nachfolgender Bereich vorhanden ist. Dies wäre wichtig, wenn die Datei von Hand bearbeitet wird. Dies würde es in diesem Fall weniger anfällig machen:

grep '^[[:blank:]]*ABB\.log[[:blank:]]*$' a.tmp

Eine einfache while-read-Schleife in der Shell würde dies implizit tun:

while read file
do 
  case $file in
    (ABB.log) printf "%s\n" "$file"
  esac
done < a.tmp


1

Ich beabsichtige, einige zusätzliche Erklärungen zu den Versuchen von OP und anderen Antworten hinzuzufügen.

Sie können die Lösung von John Kugelmans auch folgendermaßen verwenden:

grep -x "ABB\.log" a.tmp

Wenn Sie den String zitieren und dem Punkt ( .) entkommen, wird das -FFlag nicht mehr benötigt.

Sie müssen den .(Punkt) maskieren (da er mit einem beliebigen Zeichen übereinstimmt (nicht nur .), wenn er nicht maskiert ist) oder das -FFlag mit grep verwenden. -FFlag macht es zu einer festen Zeichenfolge (kein regulärer Ausdruck).

Wenn Sie die Zeichenfolge nicht zitieren, benötigen Sie möglicherweise einen doppelten Backslash, um den Punkt ( .) zu umgehen :

grep -x ABB\\.log a.tmp


Prüfung:

$ echo "ABBElog"|grep -x  ABB.log
ABBElog #matched !!!
$ echo "ABBElog"|grep -x  "ABB\.log"
#returns empty string, no match


Hinweis:

  1. -x zwingt, die ganze Linie anzupassen.
  2. Antworten mit einem nicht entkommenen Flag .ohne -FFlag sind falsch.
  3. Sie können einen -xWechsel vermeiden , indem Sie Ihre Musterzeichenfolge mit ^und umschließen $. Stellen Sie in diesem Fall sicher, dass Sie nicht verwenden -F, sondern dem entkommen ., da dies -Fdie Regex-Interpretation von ^und verhindert $.


BEARBEITEN: (Zusätzliche Erklärung in Bezug auf @hakre hinzufügen):

Wenn Sie eine Zeichenfolge ab beginnen möchten, -sollten Sie sie --mit grep verwenden. Was auch immer folgt, --wird als Eingabe verwendet (keine Option).

Beispiel:

echo -f |grep -- "-f"     # where grep "-f" will show error
echo -f |grep -F -- "-f"  # whre grep -F "-f" will show error
grep "pat" -- "-file"     # grep "pat" "-file" won't work. -file is the filename

Haben Sie tatsächlich erfahren, dass -F in Ihrem Fall fehlte? Wenn ja, können Sie bitte sagen, welcher Fall das war?
hakre

@hakre Hast du meine Antwort vollständig gelesen? Ich erklärte (ziemlich klar), warum -Fnicht benötigt wird, wenn das .richtig entkommen ist.
Jahid

Sicher. Klar, ich frage nur: War -Fverfügbar, als du das geschrieben hast? Wenn nicht, welches System haben Sie verwendet? Ich konnte diese Informationen in Ihrer Antwort bisher nicht finden, was auch jetzt noch der Fall ist, wenn ich sie erneut lese. Also wirklich sicher, ich habe Ihre Antwort mindestens zweimal vollständig gelesen. ;)
hakre

@akre war natürlich -Fvorhanden. (Ich sagte: "oder benutze -FFlagge mit grep")
Jahid

Danke für den Einblick. Es bleibt nur eine kleine Frage: Wenn -Fdie Antwort lautet, warum sollte man sich dann die Mühe machen, zu fliehen? Was ist deine Meinung dazu?
hakre

1

Das hat bei mir gut funktioniert, als ich versucht habe, etwas Ähnliches zu tun:

grep -F ABB.log a.tmp

-1
    $ cat venky
    ABB.log
    ABB.log.122
    ABB.log.123

    $ cat venky | grep "ABB.log" | grep -v "ABB.log\."
    ABB.log
    $

    $ cat venky | grep "ABB.log.122" | grep -v "ABB.log.122\."
    ABB.log.122
    $

1
Dies stimmt auch mit Dateien überein, die mit ABB.log enden, und die Punkte sollten maskiert werden.
Scrutinizer

-1

Funktioniert für mich :

grep "\bsearch_word\b" text_file > output.txt  

\b zeigt / setzt Grenzen.

Scheint ziemlich schnell zu arbeiten


Dies entspricht auch jeder Zeile, search_worddie durch Wortgrenzen getrennte Zeilen enthält . Zum Beispiel würde es mit der Zeile "foo search_word bar" übereinstimmen.
Rohan Singh

-2

Dies ist bei HPUX der Fall, wenn der Inhalt der Dateien Leerzeichen zwischen Wörtern enthält: Verwenden Sie Folgendes:

egrep "[[:space:]]ABC\.log[[:space:]]" a.tmp


Das OP wollte mit der gesamten Zeile übereinstimmen, nicht mit einem durch Leerzeichen getrennten Wort innerhalb der Zeile.
Keith Thompson


-3

Ich brauchte diese Funktion, wollte aber auch sicherstellen, dass ich keine Zeilen mit einem Präfix vor dem ABB.log zurückgab:

  • ABB.log
  • ABB.log.122
  • ABB.log.123
  • 123ABB.log

grep "\WABB.log$" -w a.tmp

Dies stimmt nur überein, wenn der führende \WWert erfüllt ist, bei dem es sich also um ein Nicht-Leerzeichen handelt xABBxlog.
bschlueter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.