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

tree一人でできる方法はありません。モードはディレクトリでは機能せず、ファイルでのみ機能します。

treeただし、ディレクトリリストをインポートしてから一致するパターンを適用すると、必要なものを簡単に達成できますgrep

tree -d tstdir -L 1 | grep '*qm*'

答え2

誰かが言及スタックオーバーフローtreesマニュアルページで、-Pスイッチがパターンと一致しない項目を除外しないのはこれです。

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-Pスイッチを使用して出力をフィルタリングすることは不可能に見えます。

編集#1

私がSOに投稿した閉じた質問から。誰、@fhauritree、そのコマンドで実行したい操作を実行する代替方法として、次の情報を公開しました。完全性のために回答に追加します。

-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[@]}"

)

関連情報