Interpretieren Sie PATTERN als eine Liste fester Zeichenfolgen, die durch Zeilenumbrüche getrennt sind und mit denen alle übereinstimmen sollen.
-x, --line-regexp
Wählen Sie nur die Übereinstimmungen aus, die genau mit der gesamten Zeile übereinstimmen.
-q, --quiet,--silent
Ruhig; Schreiben Sie nichts in die Standardausgabe. Beenden Sie das Programm sofort mit dem Status Null, wenn eine Übereinstimmung gefunden wird, auch wenn ein Fehler festgestellt wurde. Siehe auch die Option -soder --no-messages.
Fehlerbehandlung
Wie in den Kommentaren zu Recht ausgeführt, behandelt der obige Ansatz Fehlerfälle stillschweigend so, als ob die Zeichenfolge gefunden worden wäre. Wenn Sie Fehler auf andere Weise behandeln möchten, müssen Sie die -qOption weglassen und Fehler anhand des Beendigungsstatus erkennen:
Normalerweise ist der Exit-Status 0, wenn ausgewählte Zeilen gefunden werden, andernfalls 1. Der Exit-Status ist jedoch 2, wenn ein Fehler aufgetreten ist, es sei denn, die Option -qoder --quietoder --silentwird verwendet und eine ausgewählte Zeile wird gefunden. Beachten Sie jedoch, dass POSIX nur Mandate, für Programme wie grep, cmpund diff, dass der Exit - Status im Fehlerfall größer als 1 ist ; Aus Gründen der Portabilität ist es daher ratsam, eine Logik zu verwenden, die diese allgemeine Bedingung prüft, anstatt strikt mit 2 gleich zu sein.
Um die normale Ausgabe von zu unterdrücken grep, können Sie sie umleiten /dev/null. Beachten Sie, dass der Standardfehler ungerichtet bleibt, sodass alle grepmöglicherweise ausgegebenen Fehlermeldungen auf der Konsole angezeigt werden, wie Sie es wahrscheinlich möchten.
Um die drei Fälle zu behandeln, können wir eine caseAnweisung verwenden:
case`grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?`in0)# code if found;;1)# code if not found;;*)# code if an error occurred;;esac
Wenn ich diesen Befehl über ein Bash-Skript ausführe, wie kann ich 0 oder 1 in eine Variable einfangen?
Toren
6
@Toren Auf den neuesten Exit-Status kann mit zugegriffen werden $?. Sie können auch den Befehl grep neben der ifAnweisung verwenden (wie in der aktualisierten Antwort gezeigt).
Shawn Chin
5
Sie können grep -Fqx "$FILENAME"Regex-Zeichen im variablen Inhalt verwenden und müssen sich keine Gedanken darüber machen, und Sie müssen sie nicht in der Suchzeichenfolge verwenden.
Bis auf weiteres angehalten.
4
Ein paar Anmerkungen für Leute, die sich diese Antwort ansehen: 1) In bash ist 0 immer wahr und alles andere ist immer falsch. 2) Verwenden Sie das Flag -x nur, wenn die gesamte Zeile genau übereinstimmen soll. Wenn Sie nur herausfinden möchten, ob Ihre Zeichenfolge überhaupt in der Datei vorhanden ist, lassen Sie dies aus. Wenn Sie herausfinden möchten, ob Ihre Zeichenfolge genau vorhanden ist, aber nicht unbedingt mit einer ganzen Zeile übereinstimmt (dh als ganzes Wort), verwenden Sie -w.
Schmick
1
Ich verstehe nicht, ob -q / --silentes gebraucht wird? Es sagt fälschlicherweise "alles gut", um zu schlagen, selbst wenn ein Fehler auftritt. Wenn ich das richtig verstanden habe. Scheint ein fehlerhaftes Konzept für diesen Fall.
Redanimalwar
90
In Bezug auf die folgende Lösung:
grep -Fxq"$FILENAME" my_list.txt
Falls Sie sich fragen (wie ich), was -Fxqim Klartext bedeutet:
F: Beeinflusst die Interpretation von PATTERN (feste Zeichenfolge anstelle eines regulären Ausdrucks)
x: Ganze Linie abgleichen
q: Shhhhh ... minimaler Druck
Aus der Man-Datei:
-F,--fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.(-F is specified by POSIX.)-x,--line-regexp
Select only those matches that exactly match the whole line.(-x is specified by POSIX.)-q,--quiet,--silent
Quiet;do not write anything to standard output.Exit immediately with zero status if any match is
found, even if an error was detected.Also see the -s or --no-messages option.(-q is specified by
POSIX.)
-F hat keinen Einfluss auf die Dateiverarbeitung, sondern auf die Interpretation von PATTERN. Normalerweise wird PATTERN als regulärer Ausdruck interpretiert, aber mit -F wird es als fester String interpretiert.
Adam S
41
Drei Methoden in meinem Kopf:
1) Kurztest für einen Namen in einem Pfad (ich bin nicht sicher, ob dies Ihr Fall sein könnte)
ls -a "path"| grep "name"
2) Kurztest für eine Zeichenfolge in einer Datei
grep -R "string""filepath"
3) Längeres Bash-Skript mit Regex:
#!/bin/bash
declare file="content.txt"
declare regex="\s+string\s+"
declare file_content=$( cat "${file}")if[[" $file_content "=~ $regex ]]# please note the space before and after the file contentthen
echo "found"else
echo "not found"fi
exit
Dies sollte schneller sein, wenn Sie mehrere Zeichenfolgen für einen Dateiinhalt mithilfe einer Schleife testen müssen , z. B. um den regulären Ausdruck an einem beliebigen Cicle zu ändern.
Sie müssen die Ausgabe von grep nicht testen, sondern können grep einfach grep -qdirekt von ifThomas aus verwenden und aufrufen, wie es Thomas in seiner Antwort tut. Außerdem wurde nicht geprüft, ob das Verzeichnis vorhanden ist, bevor es zur Liste hinzugefügt wurde (es könnte sich schließlich um eine Liste gelöschter Verzeichnisse handeln).
Sorpigal
Ich habe das Beispielskript entfernt, es hat der Antwort von Thomas nichts hinzugefügt.
Lecodesportif
3
Wenn Sie nur das Vorhandensein einer Zeile überprüfen möchten, müssen Sie keine Datei erstellen. Z.B,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ;then# code for if it existselse# code for if it does not existfi
Die Lösung von @ Thomas hat aus irgendeinem Grund bei mir nicht funktioniert, aber ich hatte eine längere Zeichenfolge mit Sonderzeichen und Leerzeichen, sodass ich die Parameter wie folgt geändert habe:
if grep -Fxq'string you want to find'"/path/to/file";then
echo "Found"else
echo "Not found"fi
Antworten:
Der Exit-Status ist 0 (true), wenn der Name gefunden wurde, 1 (false), wenn nicht, also:
Erläuterung
Hier sind die relevanten Abschnitte der Manpage für
grep
:Fehlerbehandlung
Wie in den Kommentaren zu Recht ausgeführt, behandelt der obige Ansatz Fehlerfälle stillschweigend so, als ob die Zeichenfolge gefunden worden wäre. Wenn Sie Fehler auf andere Weise behandeln möchten, müssen Sie die
-q
Option weglassen und Fehler anhand des Beendigungsstatus erkennen:Um die normale Ausgabe von zu unterdrücken
grep
, können Sie sie umleiten/dev/null
. Beachten Sie, dass der Standardfehler ungerichtet bleibt, sodass allegrep
möglicherweise ausgegebenen Fehlermeldungen auf der Konsole angezeigt werden, wie Sie es wahrscheinlich möchten.Um die drei Fälle zu behandeln, können wir eine
case
Anweisung verwenden:quelle
$?
. Sie können auch den Befehl grep neben derif
Anweisung verwenden (wie in der aktualisierten Antwort gezeigt).grep -Fqx "$FILENAME"
Regex-Zeichen im variablen Inhalt verwenden und müssen sich keine Gedanken darüber machen, und Sie müssen sie nicht in der Suchzeichenfolge verwenden.-q / --silent
es gebraucht wird? Es sagt fälschlicherweise "alles gut", um zu schlagen, selbst wenn ein Fehler auftritt. Wenn ich das richtig verstanden habe. Scheint ein fehlerhaftes Konzept für diesen Fall.In Bezug auf die folgende Lösung:
Falls Sie sich fragen (wie ich), was
-Fxq
im Klartext bedeutet:F
: Beeinflusst die Interpretation von PATTERN (feste Zeichenfolge anstelle eines regulären Ausdrucks)x
: Ganze Linie abgleichenq
: Shhhhh ... minimaler DruckAus der Man-Datei:
quelle
Drei Methoden in meinem Kopf:
1) Kurztest für einen Namen in einem Pfad (ich bin nicht sicher, ob dies Ihr Fall sein könnte)
2) Kurztest für eine Zeichenfolge in einer Datei
3) Längeres Bash-Skript mit Regex:
Dies sollte schneller sein, wenn Sie mehrere Zeichenfolgen für einen Dateiinhalt mithilfe einer Schleife testen müssen , z. B. um den regulären Ausdruck an einem beliebigen Cicle zu ändern.
quelle
Einfacherer Weg:
Tipp: Senden Sie an,
/dev/null
wenn Sie den Beendigungsstatus des Befehls, jedoch keine Ausgaben wünschen.quelle
-q
die gleiche wie--quiet
:)-q
hier auch der besten Antwort zu und ist Vierter. keine Gerechtigkeit in dieser Welt.Der einfachste und einfachste Weg wäre:
grep -c gibt zurück, wie oft die Zeichenfolge in der Datei vorkommt.
quelle
Wenn ich Ihre Frage richtig verstanden habe, sollte dies das tun, was Sie brauchen.
In einer Zeile :
check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
quelle
grep -q
direkt vonif
Thomas aus verwenden und aufrufen, wie es Thomas in seiner Antwort tut. Außerdem wurde nicht geprüft, ob das Verzeichnis vorhanden ist, bevor es zur Liste hinzugefügt wurde (es könnte sich schließlich um eine Liste gelöschter Verzeichnisse handeln).Wenn Sie nur das Vorhandensein einer Zeile überprüfen möchten, müssen Sie keine Datei erstellen. Z.B,
quelle
Meine Version mit fgrep
quelle
-c
Option infgrep --help
Mit der Option -E verwendet grep reguläre Ausdrücke
quelle
Die Lösung von @ Thomas hat aus irgendeinem Grund bei mir nicht funktioniert, aber ich hatte eine längere Zeichenfolge mit Sonderzeichen und Leerzeichen, sodass ich die Parameter wie folgt geändert habe:
Hoffe es hilft jemandem
quelle
Eine grep-freie Lösung funktioniert für mich:
basierend auf: https://stackoverflow.com/a/229606/3306354
quelle
grep -q
In der akzeptierten Antwort beschrieben ist der effizienteste Ansatz.quelle
ls
Standardeingaben akzeptiert werden?quelle