A árvore de comandos do UNIX pode exibir apenas diretórios que correspondam a um padrão?

3

Estou tentando descobrir se existe uma maneira de obter o comando tree do UNIX para exibir somente diretórios que correspondam a um padrão específico.

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

5 directories

A página man mostra esse pouco sobre a troca.

-P pattern List only those files that match the wild-card pattern. Note: you must use the -a option to also consider those files beginning with a dot .' for matching. Valid wildcard operators are*' (any zero or more characters), ?' (any single character),[...]' (any single character listed between brackets (optional - (dash) for character range may be used: ex: [A-Z]), and [^...]' (any single character not listed in brackets) and|' sepa‐ rates alternate patterns.

Suponho que o pouco sobre ... Liste apenas os arquivos ... é o problema. Estou correto em minha interpretação de que essa opção só corresponderá aos arquivos e diretórios NÃO ?

    
por slm 21.12.2012 / 21:10

2 respostas

0

Alguém mencionou stackoverflow na página trees man, e é por isso que a opção -P não exclua as coisas que não correspondem ao padrão.

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.

Por isso, não parece ser possível obter tree para filtrar sua saída usando a opção -P.

EDIT # 1

De uma pergunta que eu publiquei no SO que foi encerrado. Alguém, @fhauri , postou as seguintes informações como formas alternativas de realizar o que eu estava tentando fazer com o tree comando. Eu estou adicionando-os à minha resposta aqui por completo.

-d switch pede para não imprimir arquivos:

    -d     List directories only.

Então, se você quiser usar isso, você pode:

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

Se você usa -L 1 ,

   -L level
          Max display depth of the directory tree.

você poderia usar melhor (no bash) essa sintaxe:

cd tstdir
echo */*qm*

ou

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

e se somente dir for necessário:

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

De forma alguma, você pode fazer isso muito rapidamente se pure bash :

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

Isso pode ser explicado:

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.

... se não houver um padrão de correspondência de arquivos, o resultado exibirá * . então para o trabalho perfeito, resta fazer:

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

(Isso seria muito mais rápido que

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

    
por 22.12.2012 / 02:28
2

Não há como tree fazer isso sozinho. Padrões não são aplicados a diretórios, apenas arquivos.

No entanto, você pode realizar facilmente o que deseja obtendo a listagem de diretórios com tree e, em seguida, aplicando o padrão de correspondência com grep .

tree -d tstdir -L 1 | grep '*qm*'
    
por 21.12.2012 / 22:23