Lista um diretório, mas somente se contiver subdiretórios?

2

No Unix, é possível usar apenas um comando para listar diretórios se eles contiverem um subdiretório?

Por exemplo, gostaria de listar o nome do diretório se ele contiver um subdiretório chamado "division_A":

/data/data_file/form_100/division_A
/data/data_file/form_101/division_A
/data/data_file/form_102/division_A

O resultado esperado seria:

form_100 
form_101 
form_102

Eu só posso usar 2 linhas de comando para realizar o objetivo.

cd /data/data_files
echo 'ls -d */division_A 2> /dev/null | sed 's,/division_A,,g''

Por isso, gostaria de perguntar se alguém pode usar um comando para prosseguir.

    
por Newbiee 02.08.2013 / 16:07

5 respostas

2

Usar ls geralmente não é uma boa ideia para analisar o sistema de arquivos. Use find para este tipo de trabalho.

lista de diretórios não vazios

Se você quiser uma lista de diretórios que não estejam vazios, você pode usar o seguinte comando:

Dados da amostra:

$ tree
.
|-- empty1
|-- empty2
|-- empty3
|-- full1
|   |-- division_A
|   |-- empty1
|   '-- full1
|       '-- afile
|-- full2
|   |-- division_A
|   |-- empty2
|   '-- full2
|       '-- afile
'-- full3
    |-- division_A
    |-- empty3
    '-- full3
        '-- afile

Você pode então usar este comando:

$  find . -mindepth 1 -not -empty -type d
./full3
./full3/full3
./full2
./full2/full2
./full1
./full1/full1

Esta é uma lista de todos os diretórios que estão NOT vazios. Essa saída pode ser limpa usando awk e uniq , se necessário.

O comando acima como compatível com POSIX seria:

$ find  . -type d -exec sh -c '[ -n "$(ls -UA "$1/" )" ]' dummy {} \; \
      -print |grep -v '^.$'

Lista de dirs. que contêm dir. division_A

Se, no entanto, você estiver procurando por uma lista de diretórios que contenham "division_A", use este comando find para fazer isso:

$ find . -type d -name "division_A" -exec dirname {} \;|sort -u
./full1
./full2
./full3

Aqui você pode usar sed para limpar a saída, se necessário:

$ find . -type d -name "division_A" -exec dirname {} \;| sed 's/\.\///' |sort -u
full1
full2
full3
    
por 02.08.2013 / 16:50
3

Se você tiver GNU find disponível, poderá usar a opção -printf para formatar a saída para imprimir apenas o diretório pai dos resultados sem precisar chamar outras ferramentas como dirname , por exemplo:

$ find
.
./data_file
./data_file/form_100
./data_file/form_100/division_A
./data_file/form_101
./data_file/form_101/division_A
./data_file/form_102
./data_file/form_102/division_A

$ find -type d -name 'division_A' -printf "%h\n"
./data_file/form_100
./data_file/form_101
./data_file/form_102
    
por 02.08.2013 / 16:21
3

com zsh :

print -rl -- **/division_A(:h:t)
    
por 02.08.2013 / 16:50
1
for f in ./*/; do [[ -d "$f"division_A ]] && echo "$f"; done

Se você quiser recursividade:

shopt -s globstar
for f in ./**/*/; do [[ -d "$f"division_A ]] && echo "$f"; done
    
por 02.08.2013 / 18:57
0

Em vez de digitar o CD nesse diretório, use isto:

echo 'ls -d /data/data_files/*/division_A 2> /dev/null | sed 's,/division_A,,g''
    
por 02.08.2013 / 16:42