grep und ein Dollarzeichen zu entkommen

31

Ich möchte wissen, welche Dateien die Zeichenfolge haben $Id$.

grep \$Id\$  my_dir/mylist_of_files

gibt 0 Vorkommen zurück.

Ich entdeckte, dass ich verwenden muss

grep \$Id$ my_dir/mylist_of_files

Dann sehe ich, dass das $Idin der Ausgabe farbig ist, dh es wurde abgeglichen.

Wie könnte ich den zweiten $abgleichen und warum funktioniert das nicht \$Id\$?

Es ist egal, ob das zweite $Zeichen das letzte ist oder nicht.

Ich benutze grep2.9.


Vor dem Posten meiner Frage habe ich Google verwendet ...

Ich habe eine Antwort gefunden

Geben Sie Folgendes ein, um in der Datei test2 nach einem $ (Dollarzeichen) zu suchen:

grep \\ $ test2

Die Zeichen \\ (doppelter Backslash) sind erforderlich, um die Shell zu zwingen, dem Befehl grep einen \ $ (einfacher Backslash, Dollarzeichen) zu übergeben. Das Zeichen \ (einfacher Backslash) weist den Befehl grep an, das folgende Zeichen (in diesem Beispiel das $) als Literalzeichen und nicht als Ausdruckszeichen zu behandeln. Verwenden Sie den Befehl fgrep, um die Notwendigkeit zu vermeiden, Escapezeichen wie den umgekehrten Schrägstrich zu verwenden.

aber ich verstehe nicht warum grep \$Idfunktioniert und warum grep \\$Id\\$nicht.

Ich bin etwas durcheinander...

Luc M
quelle

Antworten:

25

Hier gibt es zwei separate Probleme.

  1. grepVerwendet Basic Regular Expressions (BRE) und $ist ein Sonderzeichen in BREs nur am Ende eines Ausdrucks. Dies hat zur Folge, dass die 2 Instanzen von $in $Id$nicht gleich sind. Das erste ist ein normales Zeichen und das zweite ein Anker, der zum Zeilenende passt. Um das zweite $Match zu einem Literal zu machen, müssen $Sie es mit einem Backslash versehen, dh $Id\$. Das erste Escaping $funktioniert auch :, \$Id\$und ich bevorzuge dies, da es konsistenter aussieht

  2. Hier wirken zwei völlig unabhängige Escape- / Quoting-Mechanismen: Shell-Quoting und Regex-Backslash-Quoting. Das Problem ist, dass viele Zeichen, die reguläre Ausdrücke verwenden, auch für die Shell spezifisch sind. Darüber hinaus ist das Regex-Escape-Zeichen, der Backslash, auch ein Shell-Anführungszeichen. Dies ist der Grund, warum es häufig zu Problemen mit doppelten Backslashes kommt. Ich empfehle jedoch nicht, Backslashes für Shell-Anführungszeichen für reguläre Ausdrücke zu verwenden, da diese nicht sehr gut lesbar sind.

    Der einfachste Weg, dies zu tun, besteht darin, zuerst Ihre gesamte Regex in einfache Anführungszeichen wie in zu setzen 'regex'. Das einfache Anführungszeichen ist die stärkste Form des Zitierens in der Shell. Solange Ihre Regex keine einfachen Anführungszeichen enthält, müssen Sie sich nicht mehr um das Zitieren der Shell kümmern und können sich auf die reine BRE-Syntax konzentrieren.

Wenden wir dies also auf Ihr ursprüngliches Beispiel an und setzen den korrekten regulären Ausdruck ( \$Id\$) in einfache Anführungszeichen. Folgendes sollte tun, was Sie wollen:

grep '\$Id\$' my_dir/my_file

Der Grund, warum \$Id\$dies nicht funktioniert, ist, dass nach dem Entfernen von Shell-Anführungszeichen (die korrektere Art, Shell-Anführungszeichen zu verwenden) die Regex angezeigt grepwird $Id$. Wie in (1.) erläutert, stimmt dieser reguläre Ausdruck $Idnur am Ende einer Zeile mit einem Literal überein , da das erste $Literal und das zweite ein spezielles Ankerzeichen ist.

¹ Beachten Sie auch, dass das Zeichen immer etwas Besonderes ist , wenn Sie jemals zu Extended Regular Expressions (ERE) wechseln, z. B. wenn Sie sich für die Verwendung von egrep(oder grep -E) entschieden haben $. In EREs $Id$würde niemals etwas passen, da Sie nach dem Ende einer Zeile keine Zeichen mehr haben können. Dies \$Id\$wäre der einzige Weg.

jw013
quelle
3
Um zu vermeiden, dass der erste Parameter von grep als regulärer Ausdruck interpretiert wird, können Sie dies auch tun grep -F '$Id$'.
jfg956
In meinem Shell (Bash 4.3.42) grep '$Id\$' ...und grep \$Id\\$ ...Arbeit
nitsas
2
Und wenn dies ein Befehl in einer Make - Datei ist, müssen Sie auch die entkommen $mit einem voran $: grep '$$Id\$$'. stackoverflow.com/a/2382810/2097284
Camille Goudeseune
-2

So suchen Sie $Id$in einer Datei: Sie können Folgendes verwenden:grep '\$id*' filename

Bala
quelle
2
Das passt zu allem, was anfängt $id, also $ideazum Beispiel auch, nicht nur $id$.
Terdon