Ich habe eine Datei, die "dann" und "da" hat.
ich kann
$ grep "then " x.x
x and then some
x and then some
x and then some
x and then some
und ich kann
$ grep "there " x.x
If there is no blob none some will be created
Wie kann ich in einem Vorgang nach beiden suchen? Ich habe es versucht
$ grep (then|there) x.x
-bash: Syntaxfehler in der Nähe des unerwarteten Tokens `('
und
grep "(then|there)" x.x
durrantm.../code
# (Nothing)
grep
regular-expression
Michael Durrant
quelle
quelle
Antworten:
Sie müssen den Ausdruck in Anführungszeichen setzen. Der Fehler, den Sie erhalten, ist das Ergebnis einer Bash-Interpretation des
(
Zeichens als Sonderzeichen.Außerdem müssen Sie grep anweisen, erweiterte reguläre Ausdrücke zu verwenden.
Ohne erweiterte reguläre Ausdrücke, müssen Sie die entkommen
|
,(
und)
. Beachten Sie, dass wir hier einfache Anführungszeichen verwenden. Bash behandelt Backslashes in doppelten Anführungszeichen.Die Gruppierung ist in diesem Fall nicht erforderlich.
Es wäre für so etwas notwendig:
quelle
grep $'then\nthere'
undgrep -e then -e there
. Beachten Sie, dass\|
dies in BREs nicht Standard ist. Der Rest ist. Bash behandelt Schrägstriche speziell in doppelten Anführungszeichen nur vor"
,$
,\
,`
und Newline.x.x
?Nur ein kurzer Zusatz, die meisten Aromen haben einen Befehl namens egrep, der nur mit -E grep ist. Ich persönlich mag es viel besser zu tippen
Dann grep -E verwenden
quelle
Das Material, das unter REGELMÄSSIGE AUSDRÜCKE in der (oder zumindest meiner) Manpage dokumentiert ist, ist eigentlich für erweiterte reguläre Ausdrücke gedacht.
Aber grep verwendet sie nicht standardmäßig - Sie benötigen den
-E
Schalter:Weil (wieder von der Manpage):
So können Sie auch verwenden:
Da die Klammern in diesem Fall überflüssig sind.
quelle
Bashs elegante Schlichtheit scheint sich in der riesigen Manpage zu verlieren.
Zusätzlich zu den oben genannten hervorragenden Lösungen würde ich versuchen, Ihnen einen Spickzettel zu geben, wie bash Anweisungen analysiert und interpretiert . Anhand dieser Roadmap analysiere ich dann die vom Fragesteller vorgestellten Beispiele, damit Sie besser verstehen, warum sie nicht wie beabsichtigt funktionieren.
Hinweis: Shell-Skriptzeilen werden direkt verwendet. Eingegebene Eingabezeilen werden zunächst in der Historie erweitert.
Jede Bash-Zeile wird zuerst mit einem Token versehen oder mit anderen Worten in sogenannte Token zerlegt . (Das Token wird vor allen anderen Erweiterungen ausgeführt, einschließlich geschweifte Klammer, Tilde, Parameter, Befehl, Arithmetik, Prozess, Wortteilung und Dateinamenerweiterung.)
Ein Token bedeutet hier einen Teil der Eingabezeile, der durch eines der folgenden speziellen Metazeichen getrennt ist:
Bash verwendet viele andere Sonderzeichen, aber nur diese 10 erzeugen die ersten Token.
Da diese Metazeichen jedoch manchmal auch in einem Token verwendet werden müssen, muss es eine Möglichkeit geben, ihre spezielle Bedeutung zu beseitigen. Dies nennt man Flucht. Entweichenden erfolgte entweder durch eine Kette von einem oder mehreren Zeichen zu zitieren, (dh
'xx..'
,"xx.."
) oder durch einen individuellen Charakter mit einem Back-Slash Vorfixierung (dh\x
). (Es ist etwas komplizierter, da die Anführungszeichen auch zitiert werden müssen und weil doppelte Anführungszeichen nicht alles zitieren, aber diese Vereinfachung reicht vorerst aus.)Verwechseln Sie Bash-Zitate nicht mit der Idee, eine Textfolge wie in anderen Sprachen zu zitieren. Was sich zwischen Anführungszeichen in Bash befindet, sind keine Zeichenfolgen, sondern Abschnitte der Eingabezeile, bei denen Metazeichen maskiert sind, um Token nicht zu begrenzen.
Beachten Sie, dass es einen wichtigen Unterschied zwischen
'
und gibt"
, aber das ist für einen anderen Tag.Die verbleibenden nicht entkappten Metazeichen werden dann zu Token-Trennzeichen.
Beispielsweise,
Im ersten Beispiel gibt es zwei Token, die von einem Leerzeichenbegrenzer erzeugt werden:
echo
undxyz
.Ebenso im 2. Beispiel.
Im dritten Beispiel wird das Semikolon entkam, so gibt es 4 - Token von einem Leerzeichen Trennzeichen erzeugt,
echo
,x;
,echo
, undy
. Das erste Token wird dann als Befehl ausgeführt und verwendet die nächsten drei Token als Eingabe. Beachten Sie, dass der 2.echo
nicht ausgeführt wird.Die wichtige Sache zu erinnern , dass die bash erste Blicke zu entkommen Zeichen sind (
'
,"
, und\
) und sucht dann nach unescaped Meta-Zeichenbegrenzern, in dieser Reihenfolge.Wenn nicht, dienen diese 10 Sonderzeichen als
token
Begrenzer. Einige von ihnen haben auch eine zusätzliche Bedeutung, aber in erster Linie sind sie Token-Begrenzer.Was grep erwartet
In dem obigen Beispiel grep diese Token benötigt,
grep
,string
,filename
.Der erste Versuch der Frage war:
In diesem Fall
(
,)
und|
sind unescaped Meta - Zeichen und so dazu dienen , den Eingang in diese Token aufgeteilt:grep
,(
,then
,|
,there
,)
, undx.x
. grep sehen willgrep
,then|there
undx.x
.Der zweite Versuch der Frage war:
Diese tokenizes zu
grep
,(then|there)
,x.x
. Sie können dies sehen, wenn Sie grep gegen echo austauschen:quelle