So finden Sie Zeilen, die mit ** beginnen

8

Ich muss herausfinden, ob Zeilen in einer Datei mit beginnen **.

Ich kann nicht herausfinden, wie es geht, da *es von der Shell als Platzhalter interpretiert wird.

grep -i "^2" test.out

funktioniert wenn die Zeile mit einer 2 aber beginnt

grep -i "^**" test.out 

funktioniert offensichtlich nicht.

(Ich muss auch wissen, ob diese Zeile mit einem endet ), habe das aber noch nicht versucht).

Shar Hunter
quelle

Antworten:

18

Verwenden Sie das \Zeichen, um dem * zu entkommen und es zu einem normalen Zeichen zu machen.

grep '^\*\*' test.out

Beachten Sie auch das einfache Anführungszeichen 'und nicht das doppelte Anführungszeichen ", um zu verhindern, dass die Shell Dinge erweitert

Stephen Harris
quelle
3
Der erste *muss in diesem speziellen Fall nicht entkommen, fwiw.
don_crissti
5
Obwohl es nicht ausgeblendet werden muss, ist es für einen zufälligen Beobachter verwirrender, wenn das erste Sternchen nicht ausgeblendet wird, als ob Sie mit "einer beliebigen Anzahl von Zeilenanfängen gefolgt von einem Sternchen" übereinstimmen. Alles, was einen regulären Ausdruck für einen Betreuer intuitiver macht, ist eine gute Idee. =)
Auffälliger Compiler
1
Die Verwendung von doppelten Anführungszeichen würde auch die Erweiterung verhindern, nicht nur einfache Anführungszeichen. Falscher Rat hier.
Rems4e
@ rems4e mit doppelten Anführungszeichen würde verhindern, dass die Shell die Sternchen erweitert, die Backslashes jedoch nicht interpretiert. Bei doppelten Anführungszeichen müssten Sie verwenden, grep "^\\*\\*"damit grep die ^\*\*Zeichenfolge erhält, die erforderlich ist, um zu vermeiden, dass die Sternchen als Regex-Quantifizierer interpretiert werden.
Aaron
7

Da Sie die Zeile überprüfen möchten, die mit beginnt **und mit endet ), können Sie zwei grepOperationen wie folgt kombinieren :

grep '^*\*' test.out | grep ')$'

Oder mit einem einzigen grepBefehl wie diesem,

grep -E '^\*\*.*\)$' test.out

Erläuterung

  • ^\*\* : Übereinstimmungslinie, die mit beginnt **
  • .* : alles nachher zusammenbringen **
  • \)$: Übereinstimmungszeile, die auch )am Zeilenende steht.
Rahul
quelle
3

Es ist nicht die Hülle

Keine der bisherigen Antworten hat das eigentliche Problem berührt. Es wäre hilfreich zu erklären, warum es nicht wie erwartet funktioniert.

grep -i "^**" test.out

Da Sie das Muster zu grep zitiert haben , wird es von der Shell nicht erweitert. Es wird so wie es ist an grep übergeben . Dies wird auf der Handbuchseite [1] für Bash [2] erläutert :*

Durch das Einschließen von Zeichen in doppelte Anführungszeichen wird der Literalwert aller Zeichen in Anführungszeichen beibehalten, mit Ausnahme von $, `, \ und, wenn die Verlaufserweiterung aktiviert ist,!.

Es sind reguläre gewöhnliche reguläre Ausdrücke

Ein regulärer Ausdruck ist ein Muster , das eine Reihe von Zeichenfolgen beschreibt.

*ist eines der Schlüsselmuster in regulären Ausdrücken. Standardmäßig interpretiert grep es wie folgt:

* The preceding item will be matched zero or more times.

Dies bedeutet, dass Ihr Muster in seiner jetzigen ^**Form nicht viel Sinn macht. Möglicherweise wird zweimal versucht, den Zeilenanfang null oder mehrmals anzupassen. Was auch immer das heißt.

Die Lösung besteht darin, es zu zitieren :

Jedes Metazeichen mit besonderer Bedeutung kann durch einen Backslash zitiert werden.

grep -i "^\*\*" test.out


[1] Ich empfehle nicht, es zu lesen. Bitte verwenden Sie man dashstattdessen oder ähnliches.

[2] Es wurde keine Shell gegeben, daher gehe ich von Bash aus .

Rohr
quelle
2

Andere Optionen.

Sie können sedoder awkauch verwenden

$ sed -n '/^*\*/p' test.out
$ awk '/^*\*/' test.out

Um zu wissen , Linien , dass Ende mit )Verwendung auch grepoder sedoderawk

$ grep ')$' test.out
$ sed -n '/)$/p' test.out
$ awk '/)$/' test.out
Tachomi
quelle
Vielen Dank an alle! Ich bin sehr dankbar für die Hilfe in diesem Fall!
Shar Hunter
1
Und die kombinierte awk Linie: '/^*\*/&&/)$/'...
jasonwryan
0

Dies ist die völlig unzitierte Version : grep ^\\*\\* test.out. Um einen wörtlichen Backslash von der Shell an grep zu übergeben, muss dieser maskiert werden.

Dies funktioniert, solange Sie keine Dateien im Verzeichnis haben, die mit ^\einem anderen Backslash beginnen und diesen enthalten.

Schlage Bolli
quelle