
Ich habe eine Datei mit folgendem Inhalt:
sh-4.2$ cat file1
example of multiple
pattern
this is an
example of multipole
sorry multiple
pattern matching
using grep
so the example is the
file itself
-example
-multiple
-bye
tata
!
Beim Suchen nach „-example“ in der obigen Datei liefert der grep-Befehl nicht die gewünschte Ausgabe. Ich weiß, dass die Option -e verwendet werden sollte, wenn das Muster „-“ enthält:
Im ersten Beispiel habe ich-Beispieldirekt ohne Anführungszeichen:
sh-4.2$ grep -example file1
example of multiple
example of multipole
so the example is the
-example
-Beispielmit einfachen Anführungszeichen:
sh-4.2$ grep '-example' file1
example of multiple
example of multipole
so the example is the
-example
-Beispielmit doppelten Anführungszeichen und Escape-Zeichen
sh-4.2$ grep "\-example" file1
-example
sh-4.2$
Antwort1
Nun, Sie wissen, dass das Suchmuster ein '-' enthält, und Sie wissen, dass Sie das -e
Flag verwenden müssen, wenn das Suchmuster ein '-' enthält. Da Sie das Flag nicht verwenden, -e
interpretiert die Shell Ihr "Muster" stattdessen als Argument (und Parameter). Sie können das sehen mit:
$ grep "-foo" file1
grep: oo: No such file or directory
Im weiteren Sinne teilt Ihr Code der Shell mit, dass Sie ihn mit dem Argument und einem Parameter „xample“ grep "-example" file1
ausführen möchten .grep
-e
Dies ist das gleiche Problem, auf das wir stoßen, wenn wir etwas wie versuchen rm -my-silly-file-name
– es funktioniert nicht und wir müssen rm ./-my-silly-file-name
stattdessen etwas wie verwenden. Eine andere Problemumgehung wäre rm -- -my-silly-file-name
. Wir können diese Redewendung hier verwenden:
$ grep -- "-example" < file1
-example
Das "--" teilt der Shell mit, dass alles, was danach kommt,nichtein Argument.
Alternativ können Sie das "-" einfach mit einem "\" maskieren, wie Sie gesehen haben:
grep "\-example" file1
Dieser Artikel geht näher auf das Zitieren ein: der relevante Teil istParameter und Backquoted-Befehle, die von der Shell interpretiert werden sollen, sind in doppelte Anführungszeichen eingeschlossen.Wenn Sie Anführungszeichen verwenden, wird der Inhalt von der Shell interpretiert.
Antwort2
Sie wissen, dass die Option -e verwendet werden sollte, wenn das Muster mit ‚-‘ [beginnt]“, aber Sie verwenden sie nicht, obwohl Sie sie verwenden sollten. grep -e -example file1
Dadurch erhalten Sie das erwartete Ergebnis.
Folgendes wird in jedem Ihrer Beispiele tatsächlich ausgeführt:
grep -example file1
=>grep -e xample file1
(-e ist erforderlich)grep '-example' file1
=>grep -e xample file1
(-e ist erforderlich)grep "\-example" file1
=>grep \-example file1
(-e ist nicht notwendig)
Antwort3
Ein Argument, das mit beginnt, -
wird als Option betrachtet.
In Ihren ersten beiden Fällen grep
ist das erste an übergebene Argument -example
, das grep
als -e xample
( xample
Argument für die -e
Option, suchen Sie also nach xample
) verstanden wird.
Im dritten Fall \-example
wird an übergeben grep
. Da es nicht mit beginnt -
, wird es nicht als Option verwendet. Stattdessen wird es als regulärer Ausdruck verwendet. Das Verhalten für \-
ist jedoch gemäß POSIX nicht spezifiziert, sodass Sie keine Garantie dafür haben, was es abgleicht. Bei den meisten grep
Implementierungen \-
wird ein übereinstimmen -
, Sie können sich jedoch grep
Implementierungen vorstellen, bei denen \-
ein spezieller Operator sein kann (siehe beispielsweise GNU, grep
wo \+
ein spezieller Operator ist und nicht mit einem wörtlichen übereinstimmt +
).
Wenn Sie -example
nicht als Option berücksichtigt werden möchten, müssen Sie entweder:
grep -- -example file
. Das--
markiert das Ende der Optionen. Alles danach ist keine Option (also das erste Argument das zu suchende Muster und der Rest die Liste der zu durchsuchenden Dateien).grep -e -example file
. Hier-example
wird als Argument für die-e
Option genommen.
Aus diesem Grund sollten Sie sich das Schreiben angewöhnen:
grep -e "$pattern" file
Oder
grep -- "$pattern" file
wenn Sie nicht garantieren können, $pattern
dass es nicht damit beginnt -
.
Beachten Sie, dass Sie es hier auch schreiben könnten:
grep '[-]example' file
Obwohl sehenKlammerausdruck (ohne Bereiche), der mit unerwartetem Zeichen in Bash übereinstimmtüber mögliche Komplikationen bei diesem Ansatz.