nレベルの深さのサブディレクトリのみをリストする


58

Festivalは、音声パックデータを次のディレクトリ構造の例に保存します。

/usr/share/festival/voices/<language>/<voicepack name>

潜在的に多数のサブディレクトリすべてで、lsを印刷するための最も単純なワンライナー(できればを使用)は何ですか?<voicepack name><language>

回答:


80

私は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

検索とベース名の詳細

このコマンドは、このディレクトリに関して正確に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スイッチを介して呼び出します。


笑、ほとんどまったく同じ答え、素晴らしい心、そしてすべて:)。
テルドン

+1-何-exec basename {}が起こるかを考え出すときにつまずいた人のために、ここで説明できますか?
user66001

@ user66001-それで十分な説明があれば教えてください。
slm

@ user66001-それがあなたの満足にあなたの問題を解決するならば、あなたは答えの1つを受け入れることができます8
slm

1
findコマンドは、99%の時間で必要なものです。最大と最小の両方を制限することが重要でした-私は最大のみを行いました。例: find ~/ -maxdepth 1 -mindepth 1 -type d | xargs du -csh | sort -h サイズでソートされた最大のディレクトリを検索する
-oligofren

23

最も簡単なのは

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のサブディレクトリにある)/usr/share/festival/voices/ためのmindepth 2(しかし、より深い3つのレベルがダウンしていないが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.

ええ、鏡を見ているようです8
slm

+1 2人が2票を獲得したのは興味深いことです。クロス投票はそれぞれ1つを説明します;)PSディレクトリ名が欲しかったので、変更-type fするだけで-type dこれを解決するはずですよね?また、目的に関するslmの応答を待ちます-exec basename {}
-user66001

@ user66001はい、-type dディレクトリを検索します。これbasenameは非常に良いアイデアです。名前のみを出力し、パスを削除します。名前だけが必要だとすると、それがあなたがすべきことです。見ているman basenameともman dirname
テルドン

謝辞-回答としてマークを付けていないのでごめんなさい。slm 現在のバージョンには、それを必要とする人のために、より多くの情報があると感じました。
user66001

1
@ user66001まず第一に、あなたは絶対に正しいです、slmの方が確かに優れています。第二に、あなたが受け入れないことを決して謝るべきではありません。1つしか存在できず、それがあなたが最良と考えるものであるべきです:)。
テルドン

6

受け入れ答えは正しく動作しますが、それは新しい生成しますので、多少非効率的であるbasename各サブディレクトリのためのプロセスを:

find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -exec basename {} \;

可能な場合は、組み込みfindプロセスのコストを回避するために、組み込みの機能を使用することをお勧めします。 アクションfindを使用して印刷出力を変更するかなり広範な機能があります-printf。デフォルトの-print アクションではパス全体が印刷されますが-printf、フォーマット文字列を使用すると、パスの一部を選択して印刷することができます。先頭のディレクトリなしでパスのファイル名部分のみを抽出するためbasename に、フォーマット文字列は%fです。各ファイル名の後に改行を配置するには\n、次のように含めます。

$ 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

+1マイケルに答えてくれてありがとう。私はあなたの答えにもこれを行う方法の利点を見ることができますが、slmの答えに入れられた仕事を考えると、受け入れられた答えを切り替えることについて2つの心があります。@slmがこれを見て、彼よりもこれを選択することに問題がない場合は、ここに戻って受け入れられた答えを変更します。
user66001

1
@slmの答えはよく説明されておりfind、任意の外部コマンドで使用するより一般的なパターンをカバーしています。に組み込まれている操作では効率が低下しfindます。私は彼の答えにコメントを追加することを考えていましたが、それは私が持っているよりも多くの評判を必要とします。現在受け入れられている回答は正確で、十分に説明されており、より一般的な場合のパターンとして使用できるため、受け入れられた回答を変更する必要はありません。この特定の場合には、より効率的な方法があることを指摘したかっただけです。
マイケルヘンリー

0

TLDR; この質問のタイトルに基づいてここに来たばかりの人のために。「サブディレクトリをnレベルだけリストする」へ:使用

find -maxdepth N

どこNにでも番号があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.