Festival speichert Voicepack-Daten in der folgenden Beispielverzeichnisstruktur:
/usr/share/festival/voices/<language>/<voicepack name>
Was ist der einfachste Einzeiler (vorzugsweise mit ) , um nur die 's in allen möglicherweise zahlreichen Unterverzeichnissen ls
auszudrucken ?<voicepack name>
<language>
Antwort1
Ich verwende Fedora und diese Sprachpakete befinden sich an einem etwas anderen Ort:
$ ls /usr/share/festival/lib/voices/*/ -1 | grep -vE "/usr|^$"
kal_diphone
ked_diphone
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_rms_arctic_hts
nitech_us_slt_arctic_hts
Sie können dies einfach wie folgt ändern:
$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"
Verwenden von „find“
Die Verwendung ls
in dieser Weise wird normalerweise missbilligt, da die Ausgabe ls
schwer zu analysieren ist. Verwenden Sie besser den find
Befehl wie folgt:
$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -exec basename {} \;
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone
Details zu „Finden“ und „Basisname“
Dieser Befehl funktioniert, indem er eine Liste vollständiger Pfade zu Dateien erstellt, die in Bezug auf dieses Verzeichnis genau 2 Ebenen tief liegen:
/usr/share/festival/lib/voices
Diese Liste sieht folgendermaßen aus:
$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2
/usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_bdl_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_slt_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_jmk_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_clb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_rms_arctic_hts
/usr/share/festival/lib/voices/english/ked_diphone
/usr/share/festival/lib/voices/english/kal_diphon
Aber wir wollen den letzten Teil dieser Verzeichnisse, den Blattknoten. Daher können wir verwenden, basename
um ihn auszuwerten:
$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts
Wenn wir alles zusammenfassen, können wir den find
Befehl dazu bringen, jedes 2-Ebenen-tiefe Verzeichnis an den basename
Befehl zu übergeben. Die Notation basename {}
ist das, was diese Basisnamenkonvertierungen durchführt. Find ruft sie über seinen -exec
Schalter auf.
Antwort2
Am einfachsten ist
ls -d /usr/share/festival/voices/*/*
Dies wird von der Shell in alle Unterverzeichnisse /usr/share/festival/voices/
und dann in den Inhalt jedes dieser Unterverzeichnisse erweitert.
Wenn Sie, wie Ihr Titel nahelegt, nur bis zu einer bestimmten Ebene absteigen möchten, mit einigen Implementierungen von find
GNU und einigen BSD:
find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d
Damit werden alle Verzeichnisse ( ) gefunden -type d
, die in einem Unterverzeichnis von /usr/share/festival/voices/
liegen, mindepth 2
aber nicht tiefer als 3 Ebenen ( maxdepth 3
) sind. Von man find
:
-maxdepth levels
Descend at most levels (a non-negative integer) levels of direc‐
tories below the command line arguments. -maxdepth 0
means only apply the tests and actions to the command line
arguments.
-mindepth levels
Do not apply any tests or actions at levels less than levels (a
non-negative integer). -mindepth 1 means process all files
except the command line arguments.
Antwort3
Derakzeptierte Antwortbasename
funktioniert korrekt, ist aber etwas ineffizient, da es für jedes Unterverzeichnis einen neuen Prozess erzeugt :
find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -exec basename {} \;
Wenn möglich, ist es vorzuziehen, integrierte Funktionen zu verwenden, find
um den Aufwand für das Erstellen von Prozessen zu vermeiden. find
verfügt über eine ziemlich umfangreiche Möglichkeit, seine gedruckte Ausgabe mithilfe der -printf
Aktion zu ändern. Die Standardaktion -print
druckt den gesamten Pfad, aber mithilfe -printf
einer Formatzeichenfolge können Sie Teile des Pfads zum Drucken auswählen. Um nur den Dateinamenteil des Pfads ohne die führenden Verzeichnisse zu extrahieren (wie dies der basename
Fall ist), lautet die Formatzeichenfolge %f
. Um nach jedem Dateinamen eine neue Zeile einzufügen, fügen Sie \n
Folgendes ein:
$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -printf '%f\n'
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone
Antwort4
Für jemanden, der Bash verwendet und etwas Einfaches sucht, indem er einfach ls verwendet:
ls -d $PWD/*
Achten Sie beim Erstellen eines Alias (in ~/.bash_aliases oder wo auch immer) darauf, einfache Anführungszeichen zu verwenden:
alias ldf='ls -d $PWD/*'
Wenn Sie es nicht in Anführungszeichen setzen, versucht die Shell, ls auszuführen.
Durch doppelte Anführungszeichen wird der Alias mit dem Wert $PWD zum Zeitpunkt des Alias erstellt.
Sie können $(pwd) verwenden, wenn Sie möchten, aber ich sehe keinen Sinn darin, eine Unter-Shell zu erstellen, wenn Bash $PWD für Sie bereitstellt.