2015-01-27 11 views
23

Ich habe den folgenden Befehl versucht, aber ich Schwierigkeiten habe es zu interpretieren:Was bedeuten Doppelstern-Platzhalter?

ls ** 

aber ich bin mir nicht genau sicher, was es ausgibt und warum das ist das Ergebnis.

+1

Was ist der Ausgang? Unterscheidet es sich von der Ausgabe von "ls *"? –

+0

Unix Bash Globbing von zwei Sternchen Pfad mit Dateiname für rekursive Suche –

Antwort

-9

Betrachten Sie den folgenden Verzeichnisbaum:

folderA 
├── file1 
├── file2 
└── folderB 
    ├── file3 
    └── folderC 

ls alle Objekte im aktuellen Ordner auflisten:

$ ls 
file1 file2 folderB 

ls * alle Objekte im aktuellen Ordner auflisten und zusätzlich eine weitere Ebene rekursiv

$ ls * 
file1 file2 

folderB: 
file3 folderC 
+9

'**' und '*' sind nicht unbedingt identisch; Sieh meine Antwort. –

+1

Welcher Testfall? Das OP hat nichts über die Ausgabe gesagt. –

+1

Was ist mit 'ls **'? – frmsaul

1

Si Ähnlich dem Befehl DOS dir besteht die Funktion des Befehls ls darin, Dateien und Verzeichnisse aufzulisten. Wenn das Ding, das aufgelistet werden soll, eine Datei ist, listet der Befehl einfach die Datei auf, keine große Sache. Wenn die aufgelistete Sache ein Ordner ist, listet der Befehl den Inhalt des Ordners auf. Wenn Sie nur den Befehl ls ohne Argumente verwenden, ist das Standardverzeichnis Arbeitsverzeichnis oder aktueller Ordner. (Auch der Name des aktuellen Ordners ist immer ., so dass der nackte ls Befehl entspricht ls ..)

Beispiel: Sie haben in Ihrem aktuellen Ordner eine Datei mit dem Namen file_001, ein Ordner folder_002 benannt und in dem Ordner, den Sie haben Dateien mit den Namen picture_003 und picture_004. Wenn Sie ls eingeben, sehen Sie file_001 folder_002, und wenn Sie ls folder_002 eingeben, sehen Sie picture_003 picture_004.

In Unix wird die Wildcard-Verarbeitung von der Shell ausgeführt. Wenn Sie ls ** eingeben, verarbeitet Ihre Shell die **, bevor sie den Befehl ls ausführt, ersetzt sie die ** durch die Namen aller übereinstimmenden Dateien/Ordner. (Die * Platzhalter entspricht eine Datei oder einen Ordner. Mit ** Matches eine Datei oder einen Ordner, dessen Name mit etwas beginnt und endet mit etwas, so ist es funktional äquivalent zu nur *.)

In diesem Fall, wenn der ls Befehl ausgeführt wird, sind die Befehlszeilenargumente eine Liste aller Dateien und Ordner im aktuellen Ordner, so als ob Sie sie alle selbst eingegeben hätten. In unserem Beispiel führen Sie jetzt den Befehl ls file_001 folder_002 aus. Wenn der Befehl ls seine Befehlszeile verarbeitet, ist das erste Element eine Datei, also listet es einfach die Datei auf, und das zweite Element ist ein Ordner, der den Inhalt des Ordners auflistet. Da der Befehl mehr als eine Sache auflistet, druckt er zusätzlich eine Bezeichnung mit dem Namen des Ordners, so dass Sie den Inhalt des Ordners in der Ausgabeauflistung von dem unterscheiden können, was sonst noch aufgelistet wird. Als Ergebnis wird die Ausgabe des Befehls ls ** wie folgt aussehen:

file_001 

folder_002: 
picture_003 picture_004` 

Ich bin gespannt, though. Welche Anleitung, Buch oder Dokument schlug vor, dass Sie den Befehl ls ** versuchen?

+2

'**' und '*' sind nicht unbedingt identisch; Sieh meine Antwort. –

+0

Nun, das ist eine neue und unwillkommene Veränderung ... Ah, nun. Zumindest ist es nicht standardmäßig. –

+2

Was ist nicht willkommen? Ich finde es sehr nützlich; Es vereinfacht eine Menge von Befehlen, die sonst die Ausgabe von 'find' erfordern würden. –

54

Es ist wahrscheinlich eine spezielle Eigenschaft einiger Shells verwenden, die ** eine rekursive Übereinstimmung machen können, im Gegensatz zu einer einzelnen *, die nur im aktuellen Verzeichnis übereinstimmt.

Der Platzhalter * stimmt mit jeder Datei oder jedem Verzeichnis (dessen Name nicht mit . beginnt) im aktuellen Verzeichnis überein.

Je nachdem, welche Shell Sie verwenden, und mit welchen Einstellungen, **kann-* gleichwertig sein; es könnte mit null oder mehr Zeichen gefolgt von null oder mehr Zeichen übereinstimmen, was dem gleichen entspricht, wenn null oder mehr Zeichen nur einmal gefunden werden.

Aber mit einigen Shells, mit einigen Einstellungen, ist ** eine rekursive Version von *, passend zu allen Dateien und Verzeichnissen im aktuellen Verzeichnis und Unterverzeichnissen.

Zitiert die bash manual:

`*‘
Spiele eine beliebige Zeichenfolge, einschließlich der Null-String. Wenn die Shell-Option "globstar" aktiviert ist und "*" in einem Erweiterungskontext des Dateinamens verwendet wird, werden zwei benachbarte '*' als einzelnes Muster verwendet und passen auf alle Dateien und null oder mehr Verzeichnisse und Unterverzeichnisse. Wenn ein `/ 'folgt, stimmen zwei benachbarte'` * - Dateien nur mit Verzeichnissen und Unterverzeichnissen überein.

Dies funktioniert nur, wenn die Option globstar über gesetzt:

shopt -s globstar 

(es ist standardmäßig deaktiviert ist) und nur in relativ neueren Versionen von bash.

Ich glaube, zsh unterstützt auch diese Syntax.

Es ist wichtig zu beachten, dass Platzhalter durch die Shell erweitert werden, nicht durch den Befehl ls. Wenn Sie ls ** oder ls *.txt eingeben, sieht der Befehl ls selbst nie die * Zeichen; Es sieht nur eine erweiterte Liste von Dateien, als ob Sie die gesamte Liste in der Befehlszeile eingegeben hätten.

3

Das genaue Verhalten dieses bestimmten Platzhalters wurde von den anderen Antworten gut abgedeckt, aber Informationen über den allgemeinen Fall können nützlich sein.

Dieses Verhalten ist nicht auf ls beschränkt und wird als "Globbing" bezeichnet. Hierbei handelt es sich um die Erweiterung von Mustern basierend auf Übereinstimmungen mit vorhandenen Dateinamen. Es ist wichtig zu beachten, dass diese Muster keine Syntax für reguläre Ausdrücke verwenden.

Die Shell verarbeitet die Argumente vor, bevor sie an das Programm gesendet werden. Es gibt im Allgemeinen mehrere Ebenen der Expansion, einige davon beinhalten Globbing.

Eine große Ressource für weitere Informationen über die anderen Platzhalter in einem Datei-Glob-Muster verfügbar ist die Unix-Manpage. Eine Online-Version für Glob kann here gefunden werden.

Schließlich ein einfaches Beispiel, was dies für Sie tun kann, besonders in Kombination mit anderen Shell-Erweiterungen, in diesem Fall die von der Shell bash zur Verfügung gestellt. Informationen über die in diesem Beispiel verwendeten Erweiterungen finden Sie in der Bash Guide for Beginners - was trotz des Titels meine goto-Ressource ist.

ls *{01..04}.{txt,csv} wird ls *01.txt *01.csv *02.txt *02.csv *03.txt *03.csv *04.txt *04.csv

Welche Ausgabe etwas wie dies könnte:

input_01.txt input_02.txt input_03.txt input_04.txt output_01.csv output_02.csv output_03.csv output_04.csv 

Während diese Überspringen:

input_05.txt input_06.txt input_07.txt input_08.txt input_09.txt input_10.txt output_05.csv output_06.csv output_07.csv output_08.csv output_09.csv output_10.csv 

Ein triviales Beispiel, aber wenn Sie wissen, dass dieses Verhalten nicht spezifisch zu ls, dann können Sie sich das Dienstprogramm vorstellen, wenn es mit mv,gekoppelt wird, rsync usw.