Festival は、次の例のディレクトリ構造にボイスパック データを保存します。
/usr/share/festival/voices/<language>/<voicepack name>
潜在的に多数のサブディレクトリすべてでls
だけを出力する最も単純なワンライナー ( を使用するのが望ましい) は何ですか?<voicepack name>
<language>
答え1
私は Fedora を使用していますが、これらのボイスパックは少し異なる場所にあります:
$ 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
これを次のように変更することができます:
$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"
検索の使用
この方法で を使用することはls
、 の出力ls
を解析するのが難しいため、通常は好ましくありません。find
次のように コマンドを使用する方がよいでしょう。
$ 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
find & basename の詳細
このコマンドは、このディレクトリに対して正確に 2 レベルの深さにあるファイルへの完全なパスのリストを生成することによって機能します。
/usr/share/festival/lib/voices
このリストは次のようになります:
$ 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
しかし、私たちが欲しいのはこれらのディレクトリの最後の部分、つまりリーフノードです。basename
それを利用すると解析できます。
$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts
これらをすべてまとめると、find
コマンドが 2 レベルの深さの各ディレクトリをbasename
コマンドに渡すようになります。表記法basename {}
は、これらのベース名の変換を行うものです。Find は、-exec
スイッチを介してこれを呼び出します。
答え2
一番簡単なのは
ls -d /usr/share/festival/voices/*/*
これはシェルによってすべてのサブディレクトリに展開され/usr/share/festival/voices/
、その後、各サブディレクトリの内容に展開されます。
find
タイトルが示唆するように、 GNU や BSD などの実装を使用して特定のレベルまで降りたいだけの場合:
find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d
これにより、-type d
のサブディレクトリ内にあるが、3 レベルより下 ( )未満のすべてのディレクトリ ( ) が検索されます。/usr/share/festival/voices/
mindepth 2
maxdepth 3
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.
答え3
の受け入れられた回答basename
正しく動作しますが、サブディレクトリごとに新しいプロセスが生成されるため、やや非効率的です。
find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -exec basename {} \;
find
可能な場合は、プロセス生成のコストを回避するために、 に組み込まれている機能を使用することをお勧めします。 には、 アクションfind
を使用して印刷出力を変更するためのかなり広範な機能があります-printf
。 デフォルトの-print
アクションはパス全体を印刷しますが、 と-printf
書式文字列を使用すると、印刷用にパスの一部を選択できます。 が行うように、先頭のディレクトリなしでパスのファイル名部分だけを抽出するにはbasename
、書式文字列は です%f
。 各ファイル名の後に改行を配置するには、\n
次のように include します。
$ 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
答え4
bash を使用していて、ls を使用するだけのシンプルなものを探している人向け:
ls -d $PWD/*
エイリアスを作成するときは(~/.bash_aliases など)、必ず一重引用符を使用してください。
alias ldf='ls -d $PWD/*'
引用符で囲まないと、シェルは ls を実行しようとします。
二重引用符で囲むと、エイリアスの作成時の $PWD の値を持つエイリアスが作成されます。
必要に応じて $(pwd) を使用することもできますが、bash が $PWD を提供している場合にサブシェルを生成する意味がわかりません。