UNIXコマンドツリーは、パターンに一致するディレクトリのみを表示できますか?

UNIXコマンドツリーは、パターンに一致するディレクトリのみを表示できますか?

treeUNIXコマンドで特定のパターンに一致するディレクトリのみを表示する方法があるかどうかを確認しようとしています。

% tree -d tstdir -P '*qm*' -L 1
tstdir
|-- d1
|-- d2
|-- qm1
|-- qm2
`-- qm3

5 directories

これマニュアルページスイッチに関するいくつかの情報を表示します。

-Pモードは、ワイルドカードパターンと一致するファイルのみを一覧表示します。注:ドット.' for matching. Valid wildcard operators are* '(0文字以上)、?' (any single character),[...]'(角かっこの間にリストされている単一文字)で始まるファイルを考慮するには、-aオプションを使用する必要があります(文字範囲を表すにはオプション - (ダッシュ) )).たとえば、[AZ]) と[^...]' (any single character not listed in brackets) and|' を使用して代替パターンを区別できます。

おおよそ推測しています...該当するファイルのみを一覧表示します...問題です。このスイッチがファイルに対してのみパターンマッチングを実行するという私の解釈は正しいですか?いいえ目次?

編集#1

@f-ハウリマニュアルページで利用可能なスイッチを使用すると、これが期待どおりに機能しない最良の理由があるようですtree。エラー部分でこれを逃しましたね。

BUGS
   Tree  does not prune "empty" directories when the -P and -I options are
   used.  Tree prints directories as it comes to them, so  cannot  accumu‐
   late  information  on files and directories beneath the directory it is
   printing.

これらの制限を考慮すると、tree包括的なフィルタリストを実行するのに最適な方法ではありませんが、排他的フィルタリストは-Iこのスイッチを使用する代わりに使用できます。

代わりに、シェルワイルドカード、findコマンド、またはPerlスクリプトがこれを行うのに適した方法です。バラより寄稿者: @f-hauriこれは、これらの選択肢のいくつかに良い答えです。

ベストアンサー1

うんこれ抜け穴。マニュアルページから:

BUGS
   Tree  does not prune "empty" directories when the -P and -I options are
   used.  Tree prints directories as it comes to them, so  cannot  accumu‐
   late  information  on files and directories beneath the directory it is
   printing.

...とにかく-d質問の切り替えいいえ文書印刷:

    -d     List directories only.

したがって、これを使用したい場合は、次のことができます。

tree tstdir -P '*qm*' -L 1 | grep -B1 -- '-- .*qm'
|-- id1
|   `-- aqm_P1800-id1.0200.bin
--
|-- id165
|   `-- aqm_P1800-id165.0200.bin
|-- id166
|   `-- aqm_P1800-id166.0200.bin
--
|-- id17
|   `-- aqm_P1800-id17.0200.bin
--
|-- id18
|   `-- aqm_P1800-id18.0200.bin
--
|-- id2
|   `-- aqm_P1800-id2.0200.bin

-L 1全体的に、あなたが使うなら

   -L level
          Max display depth of the directory tree.

次の構文を(bashで)よりよく使用できます。

cd tstdir
echo */*qm*

または

printf "%s\n" */*qm*

dirだけが必要な場合:

printf "%s\n" */*qm* | sed 's|/.*$||' | uniq

とにかく純粋なバッシュ:

declare -A array;for file in  */*qm* ;do array[${file%/*}]='';done;echo "${!array[@]}"

これは次のように解釈できます。

cd tstdir
declare -A array          # Declare associative array, (named ``array'')
for file in  */*qm* ;do   # For each *qm* in a subdirectory from there
    array[${file%/*}]=''  # Set a entry in array named as directory, containing nothing
  done
echo "${!array[@]}"         # print each entrys in array.

...パターンに一致するファイルがない場合は、結果が表示されます*。したがって、タスクを完全に完了するには、次の作業も必要です。

resultList=("${!array[@]}")
[ -d "$resultList" ] || unset $resultList

(これよりも良いでしょう。

declare -A array
for file in  */*qm*; do
    [ "$file" == "*/*qm*" ] || array[${file%/*}]=''
  done
echo "${!array[@]}"

)

おすすめ記事