Dies funktioniert in Bash 4:
ls -l {,**/}*.ext
Damit der Doppelstern-Glob funktioniert, muss die globstar
Option festgelegt werden (Standard: Ein):
shopt -s globstar
Von man bash
:
Globstar
Wenn festgelegt, wird das in einer Dateinamenerweiterung verwendete Muster ** verwendet
Text stimmt mit Dateien und null oder mehr Verzeichnissen überein und
Unterverzeichnisse. Wenn dem Muster nur ein / folgt, nur
Verzeichnisse und Unterverzeichnisse stimmen überein.
Jetzt frage ich mich, ob es vielleicht einmal einen Fehler in der Globstar-Verarbeitung gegeben hat, denn jetzt erhalte ls **/*.ext
ich einfach die richtigen Ergebnisse.
Unabhängig davon habe ich mir die Analyse angesehen, die Kenorb mit dem VLC-Repository durchgeführt hat, und einige Probleme mit dieser Analyse und in meiner Antwort unmittelbar oben festgestellt:
Die Vergleiche mit der Ausgabe des find
Befehls sind ungültig, da die Angabe -type f
keine anderen Dateitypen (insbesondere Verzeichnisse) enthält und die ls
aufgeführten Befehle dies wahrscheinlich tun. Außerdem gibt einer der aufgelisteten Befehle ls -1 {,**/}*.*
- der anscheinend auf meinem oben genannten basiert - nur Namen aus , die einen Punkt für die Dateien enthalten, die sich in Unterverzeichnissen befinden. Die Frage des OP und meine Antwort enthalten einen Punkt, da nach Dateien mit einer bestimmten Erweiterung gesucht wird.
Am wichtigsten ist jedoch, dass es ein spezielles Problem bei der Verwendung des ls
Befehls mit dem Globstar-Muster gibt **
. Viele Duplikate entstehen, da das Muster von Bash auf alle Dateinamen (und Verzeichnisnamen) im untersuchten Baum erweitert wird. Nach der Erweiterung ls
listet der Befehl jeden von ihnen und ihren Inhalt auf, wenn es sich um Verzeichnisse handelt.
Beispiel:
In unserem aktuellen Verzeichnis befindet sich das Unterverzeichnis A
und sein Inhalt:
A
└── AB
└── ABC
├── ABC1
├── ABC2
└── ABCD
└── ABCD1
**
Erweitert in diesem Baum zu "AA / AB A / AB / ABC A / AB / ABC / ABC1 A / AB / ABC / ABC2 A / AB / ABC / ABCD A / AB / ABC / ABCD / ABCD1" (7 Einträge) . Wenn Sie dies tun echo **
, erhalten Sie genau die Ausgabe, die Sie erhalten, und jeder Eintrag wird einmal dargestellt. Allerdings , wenn Sie das tun , ls **
es wird eine Liste der zur Ausgabe jeder dieser Einträge. Im Wesentlichen ls A
folgt also ls A/AB
usw., wird also A/AB
zweimal angezeigt. Außerdem ls
wird die Ausgabe jedes Unterverzeichnisses voneinander unterschieden:
...
<blank line>
directory name:
content-item
content-item
Wenn Sie also zählen, werden wc -l
alle Leerzeilen und Abschnittsüberschriften der Verzeichnisnamen verwendet, wodurch die Zählung noch weiter verschoben wird.
Dies ist ein weiterer Grund, warum Sie nicht analysieren solltenls
.
Als Ergebnis dieser weiteren Analyse empfehle ich, das Globstar-Muster unter keinen anderen Umständen zu verwenden, als auf folgende Weise über einen Dateibaum zu iterieren:
for entry in **
do
something "$entry"
done
Als letzten Vergleich habe ich ein Bash-Quell-Repository verwendet, das ich zur Hand hatte, und dies getan:
shopt -s globstar dotglob
diff <(echo ** | tr ' ' '\n') <(find . | sed 's|\./||' | sort)
0a1
> .
Ich habe tr
Leerzeichen in Zeilenumbrüche geändert, was hier nur gültig ist, da keine Namen Leerzeichen enthalten. Ich habe sed
die führenden ./
Zeilen aus jeder Ausgabezeile entfernt find
. Ich habe die Ausgabe von sortiert, find
da sie normalerweise unsortiert ist und Bashs Erweiterung der Globs bereits sortiert ist. Wie Sie sehen können, war die einzige Ausgabe von diff
die aktuelle Verzeichnisausgabe .
von find
. Als ich das tat, hatte ls ** | wc -l
die Ausgabe fast doppelt so viele Zeilen.
**/*.ext
. Sind Sie sicher, dass es bei Ihnen funktioniert?