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

1

Estou tentando descobrir se existe uma maneira de obter o comando tree do UNIX para exibir apenas 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 ?

EDIT # 1

@ f-hauri parece ter a melhor razão para isso não funcionar como um pensaria nos switches disponíveis na página tree man. Eu perdi esse bit na seção BUGS.

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.

Devido a essa limitação, parece que tree não é a melhor maneira de realizar uma lista filtrada inclusiva, mas uma lista filtrada exclusiva seria uma maneira alternativa de usar a opção -I .

Em vez disso, seria semelhante a qualquer curinga de shell, o comando find ou um script Perl seria uma maneira mais apropriada de realizar isso. Veja a resposta bem do @f-hauri para alguns desses métodos alternativos.

    
por slm 21.12.2012 / 21:06

2 respostas

5

Sim, é um bug . De man page:

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.

... nada, -d 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ê poderia 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 aperfeiçoar o trabalho, 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 21.12.2012 / 23:00
1

Você pode usar meu comando do arbo . Instalar com:

ln -s "$PWD"/arbo.py ~/bin/arbo

Agora você pode fazer:

find tstdir -maxdepth 1 -iname '*qm*' |arbo --color

A saída é algo como isto, com as mesmas cores que ls:

git arbo
bedup
├─ __init__.py
├─ __main__.py
├─ platform/__init__.py
├─ termupdates.py
├─ test_bedup.py
└─ tracking.py
setup.py
tox.ini
    
por 17.01.2013 / 16:16