Sie könnten an „dem armen Mann find
“ interessiert sein :
shopt -s globstar
shopt -s
s ets die benannte Shell Option (en). Die globstar
Option ist in Bash (1) wie folgt definiert :
Wenn festgelegt, stimmt **
das in einem Dateinamen- / Pfadnamen-Erweiterungskontext verwendete Muster mit einer Datei [sic] und null oder mehr Verzeichnissen und Unterverzeichnissen überein . Wenn dem Muster ein folgt /
, stimmen nur Verzeichnisse und Unterverzeichnisse überein.
Nachdem Sie dies getan haben shopt -s globstar
, können Sie einen der folgenden Befehle ausführen:
ls -d1 - source / ** # Das Zeichen nach dem 'd' ist die Ziffer.
ls -d - source / ** | cat # dh es schreibt das in eine Pipe zu einem beliebigen Befehl.
printf "% s \ n" source / **
erzeugt die Ausgabe:
source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png
Dies schließt leider auch die Verzeichnisnamen ein. Es könnte Ihnen ein wenig helfen, das zu wissen
printf "%s\n" source/**/
erzeugt die Ausgabe:
source/
source/fonts
source/images
dh nur die Verzeichnisnamen. Sie könnten die Ausgabe eines des ersten Satzes von Befehlen in eine Datei, leiten Sie die Ausgabe der oben auf eine zweite Datei umleiten, und dann verwenden comm
, diff
oder etwas ähnliches, die zweite Datei aus dem ersten abzuziehen, nur die Ebene verlassen Dateien (Nichtverzeichnisse). Aber tu das nicht.
Ein anderer Ansatz (der nicht viel besser ist) ist
ls -d --file-type -- source/** | grep -v '/$'
Die --file-type
Option weist Sie ls
an, /
am Ende jedes Verzeichnisnamens (und andere Zeichen am Ende anderer (spezieller) Dateitypen) Folgendes anzuzeigen :
source // # Eine zusätzliche
Quelle hinzugefügt / font / # Eine hinzugefügt
source / fonts / fontello
Quelle / Bilder / # Eine hinzugefügt
source / images / bg1.png
source / images / eng.png
source / images / fra.png
und dann grep -v '/$'
entfernt das die Zeilen, die mit enden /
; dh die Verzeichnisnamen. Leider wird die --file-type
Option von POSIX nicht angegeben . Wenn Ihre Version ls
dies nicht unterstützt, verwenden Sie -F
. Das ist so, --file-type
außer dass es auch ein *
am Ende der Namen ausführbarer Dateien anzeigt , was manche Leute als störend empfinden. Sie können sie beseitigen mit sed
:
ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'
Wenn Sie mit allen Dateien (und nur mit den Dateien) etwas tun möchten, können Sie dies tun
für f in source / **
machen
if [-f "$ f"]
dann
Fügen Sie hier Befehle ein, die auf einfache Dateien angewendet werden sollen.
fi
erledigt
Anmerkungen:
- Wenn
ls
mit einem Anschluss ausgegeben wird , und es ist nicht in -l
( l ong) Modus, schreibt er mehrere Namen pro Zeile (es sei denn , die Namen sehr lang sind). Sie können erzwingen, einen Namen pro Zeile zu schreiben, indem Sie -1
(eins) angeben oder die Ausgabe in eine Datei oder eine Pipe umleiten.
- Sie wahrscheinlich nicht wirklich brauchen die
--
in den ls
Befehlen , da Sie ein Verzeichnis , dessen Inhalt sind die Auflistung Sie erstellt. Sie sollten es verwenden, wenn Sie *
in einem unbekannten Verzeichnis auflisten , um sich vor Dateinamen zu schützen, die mit beginnen -
.
- Versuchen Sie nicht, die Ausgabe von zu analysieren
ls
.
- Die
globstar
Shell-Option scheint nicht von POSIX definiert zu sein. (In der Tat, ich bin nicht sicher , POSIX erkennt keine Shell - Optionen.) Während es scheint zu sein bash
ism, Vorsicht - es ist nicht in allen Versionen von bash vorhanden sein könnten.
Wenn fonts
oder images
Unterverzeichnisse hat, **
werden sie alle rekursiv bis zum Ende aufgelistet. Eine (etwas klobige und unzuverlässige) Möglichkeit, die Tiefe zu begrenzen, ist
ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
Dadurch werden Zeilen entfernt, die drei oder mehr /
Zeichen enthalten.
find
falsch zu verwenden . Insbesondere wenn Sie laufenfor file in $(find ...)
, haben Sie eine davon getroffen.)