Was ist die Natur des Grep-Befehls?

Was ist die Natur des Grep-Befehls?

Ich wollte alle TXT-Dateien mit dem Platzhalterzeichen „*“ durchsuchen.
Ich habe diesen Befehl (auch ohne Anführungszeichen „“) ausprobiert, aber er hat nicht funktioniert.

ls | grep "*.txt"

Das Interessante ist, dass es funktioniert, wenn ich im Grep-Befehl ein anderes Zeichen einfüge, das einer TXT-Datei im Verzeichnis entspricht.

>>ls | grep s*.txt
sample.txt

Ich weiß, dass das ls *.txtfunktionieren wird, aber ich war etwas überrascht über die Art des Grep-Befehls. Kann mir jemand helfen, warum das passiert?

Liegt es daran, dass grep reguläre Ausdrücke verwendet? Bitte helfen Sie.

Antwort1

In regulären Ausdrücken *bedeutet „eine beliebige Anzahl des vorherigen Elements“, nicht „eine beliebige Anzahl beliebiger Zeichen“, wie es in Shell-Mustern der Fall ist. Und .bedeutet „jedes einzelne Zeichen“. Um also nach „irgendetwas, gefolgt von einem wörtlichen .txt„“ zu suchen, würden Sie verwenden .*\.txt. Oder einfach \.txt, da reguläre Ausdrücke normalerweise überall in der Zeile nach der Übereinstimmung suchen. Dann \.txtwürde auch wieder ein Dateiname wie übereinstimmen foo.txtgz, da das .txtnicht am Ende stehen müsste. Sie müssten \.txt$das Muster am Zeilenende sperren.

Der reguläre Ausdruck *.txtist entweder bedeutungslos, ein Fehler oder sucht nach einem wörtlichen Asterisk, abhängig von der Implementierung und davon, ob Sie einfache reguläre Ausdrücke ( grep) oder erweiterte reguläre Ausdrücke ( grep -E) verwenden. Verwenden Sie ihn am besten nicht.

Andererseits s*.txtwürde nach „beliebige Anzahl von Buchstaben s, dann ein beliebiges einzelnes Zeichen, dann Literal txt“ gesucht. Das ist ein gültigerer regulärer Ausdruck, aber … stimmt trotzdem nicht mit überein sample.txt.

Stattdessen passiert in Ihrem zweiten Befehl Folgendes: Da s*.txtes nicht in Anführungszeichen steht, erweitert die Shell das , s*.txtbevor grepes angezeigt wird. Wenn die einzige passende Datei ist sample.txt, grepsucht es in der Ausgabe von danach ls. (Wenn es mehrere passende Dateinamen gäbe, würde der erste als Muster und der Rest als zu greplesende Dateinamen verwendet. In diesem Fall würde die Eingabe aus der Pipe ignoriert.)


Aber, lskann eine Liste von Dateien auch nehmen, so während Sie verwenden könnten

ls | grep '\.txt'

Um eine Datei abzurufen .txt, wäre es wahrscheinlich einfacher, einfach

ls *.txt 

stattdessen.

Antwort2

Das liegt zum Teil daran, dass grepreguläre Ausdrücke verwendet werden (tatsächlich resteht das im Namen dafür - es ist die Abkürzung fürGlobalRregelmäßigtAusdruckPDruck).

Das *Platzhalterzeichen in regulären Ausdrücken unterscheidet sich vom *Platzhalterzeichen beim Shell-Globbing.

In regulären Ausdrücken *bedeutet "null oder mehr des zuvor definierten Objekts". Allerdings .istAuchein Platzhalter, der „ein Zeichen“ bedeutet.

Bedeutet in Shell-Globs *„null oder mehr Zeichen“. .ist überhaupt kein Platzhalter.

Wenn Sie grepnach dem Muster suchen "*.txt", suchen Sie nach null oder mehr von irgendetwas, gefolgt von genau einem weiteren Zeichen, gefolgt von der Literalzeichenfolge txt.

Wenn Sie grepfür das Muster "s*.txt"m you are looking for a literals , followed by zero or mores s, followed by any character, followed by the literal stringtxt`.

Aus diesem Grund finden Sie in regulären Ausdrücken häufig das .*, was „ein beliebiges Zeichen gefolgt von null oder mehr beliebigen Zeichen“ bedeutet. Regex für „buchstäblich jede beliebige Zeichenkombination außer null Zeichen“.

Wenn Sie ls *.txtder Shell sagen: „Suchen Sie nach allen Dateinamen, die dem Glob-Muster entsprechen *.txt, listen Sie sie hier auf und geben Sie sie als Argumente für den lsBefehl an.“

Antwort3

Bitte beachten Sie, dass grep die Datei durchsuchtInhaltwobei das erste Argument das Suchmuster ist und die anderen Argumente als zu untersuchende DATEIEN interpretiert werden

es wird Ihnen klarer, wenn Sie grep -H -oFlags verwenden oder Ihre grepin ein Skript einfügen und es ausführen, bash -x scriptum zu sehen, wie Shell-Globs erweitert werden, bevor sie als Argumente übergeben werden

verwandte Informationen