O comando 'ls -d' não está exibindo diretórios. Existe uma maneira de obter 'ls' para exibir apenas diretórios em vez de arquivos e diretórios?

44

Existe uma maneira de conseguir lsexibir apenas diretórios em vez de arquivos e diretórios?

Na página do manual:

   -d, --directory
          list directory entries instead of contents, and do not  derefer
          ence symbolic links

Portanto, se eu digitar no /diretório, espero ver apenas os diretórios. Em vez disso, mostra "."

$ cd /
$ ls -d
.

Eu esperava ls -dme mostrar isso:

$ ls -d
bin    data  home        opt    sbin  sys      var
boot   dev   lib         media  proc  selinux  tmp
cdrom  etc   lost+found  mnt    root  srv      usr

Existe uma maneira de conseguir lsexibir apenas diretórios em vez de arquivos e diretórios?

nelaaro
fonte
17
LSD pode ser muito confuso.
boehj
2
@jin ls -d * / funciona. Mas por que eu tenho que "* /" para colocar o que quero.
N
8
@nelaar -dnão significa listar apenas diretórios, significa não listar o conteúdo do diretório. Tente digitar ls */e você verá o conteúdo de todos os diretórios.
21711 Jin
2
Tenho ldiralised a ls -d */no meu .bashrcpara fazer isso mais fácil ...
DQdlM
1
Podemos fornecer toneladas de informações, mas não um único sinalizador apenas para mostrar os diretórios ...
DimiDak 15/02

Respostas:

50

Suas expectativas são baseadas no DOS Think / Windows Think e estão erradas. No MS-DOS, Windows e, de fato, em alguns outros sistemas operacionais IBM / Microsoft, a expansão de curinga é realizada pelo próprio comando, e coisas como a /aopção para o dircomando atuam como filtros de atributo durante a expansão de curinga. direxpande curingas como *, que o interpretador de comando passa para ele como está e, se /aespecificado, aplica os filtros apropriados ao que é retornado. (Em alguns sistemas operacionais, os filtros de atributo podem ser fornecidos à chamada do sistema para enumerar um diretório e o kernel do sistema operacional, ou seus drivers do sistema de arquivos, os aplica sozinho.)

No Unices e no Linux, a expansão de curinga é feita pelo shell e não tem permissões. Quando, no diretório raiz, você faz

ls *

o que o lspróprio comando recebe do shell (algo como)

ls bin home opt var boot dev tmp etc perdido + encontrado usr raiz

O que a opção -d/ --directoryfaz é desativar o que normalmente acontece a seguir . O que normalmente acontece a seguir é que lsolha cada um de seus argumentos, vê que são diretórios e decide enumerar seu conteúdo. Para argumentos que nomeiam arquivos, apenas imprime as informações do próprio arquivo. Com a -dopção, os diretórios são tratados como arquivos. Portanto, lsimprime as informações de cada um dos diretórios que são passados ​​como argumentos, como faria se fossem arquivos.

Portanto, -d não é uma opção "imprimir apenas diretórios". De fato, não apenas não existe essa opção; não pode haver essa opção. A expansão de curinga é feita pelo shell e ( shpelo menos em um POSIX ) não há como dizer ao shell para verificar a permissão e os bits do tipo de arquivo quando ele se expande *para uma lista de nomes. Para obter uma lista apenas dos nomes dos diretórios, é necessário usar o findcomando, conforme explicado por ztank1013, ou usar o truque que um nome de caminho que termina com uma barra implica na entrada do diretório ., conforme explicado em Jin. ( Jino truque termina com o lscomando recebendo os argumentos

ls bin / home / opt / var / boot / dev / tmp / etc / lost + found / root / usr /

porque o padrão */está de fato combinando nomes de caminho com dois componentes, o segundo sendo vazio e, portanto, não está fazendo exatamente o que era desejado. Em particular, ele tratará os links simbólicos que apontam para os diretórios como se fossem diretórios.)

O comportamento de ls -dsem a *é uma simples extensão do exposto acima. Simplesmente é preciso saber mais uma coisa ls: quando não é fornecido nenhum argumento, ele assume um argumento padrão de .. Agora, sem a -dopção, o comportamento mencionado acima leva ao conteúdo do diretório nomeado por .ser enumerado e as informações para seu conteúdo exibidas. Com a -dopção, o diretório .é tratado como se fosse um arquivo, e suas próprias informações são exibidas, em vez de seu conteúdo enumerado.

JdeBP
fonte
3
"não pode haver tal opção" - essa é uma afirmação bastante forte - a implementação dessa opção é óbvia: veja um argumento que não seja de diretório e ignore-o. O que não pode ser implementada é o equivalente a dir /s *.txt[sem recorrer a wildcards citando como para a descoberta]
Random832
6
Certo, mas não há razão lógica para não ter uma opção que filtre os itens que foram passados ​​como argumentos. O fato de que "a expansão curinga é divorciada do tipo de entrada verificação" é irrelevante, uma vez que este não tem nada em tudo a ver com expansão de curinga - único tipo de entrada verificação, que não há nenhuma razão que não pode ser feito inteiramente dentro ls. Se ls --color pode escurecê-los de azul, ls -F pode colocar um / depois deles e ls -l pode colocar um 'd' no modo, então alguma outra opção hipotética pode omiti-los. O fato de essa opção não existir não significa que " não possa ".
Random832
5
O Random832 faz um ponto decente: ls poderia ter uma opção para filtrar arquivos ou diretórios, e isso não é mutuamente exclusivo em fazer com que o shell faça expansão. Não há condição de corrida no ls: ele pode filtrá-lo, pois classifica os arquivos normalmente. (Já existe uma corrida entre a expansão do shell e ls, FWIW.) Acho que a expansão do shell é apenas parte do motivo: a expansão do shell (e a filtragem em geral) não é implementada no ls porque precisaria ser implementada novamente no cp , mv, etc. O Unix é um "faça uma coisa e faça bem". Se você precisar de filtragem avançada, existem ferramentas para isso.
Thanatos
2
A ls -popção adiciona um /símbolo apenas aos diretórios. Não há razão para não estender os recursos de impressão de saída com algo que apenas os produz (em vez de ls -p | grep /).
Anne van Rossum 14/03
3
@JdeBP, ataques ad-hominem ("kiddo") e arrogância (todo mundo, exceto você não conhece "os fundamentos do Unix") não pertencem a uma discussão técnica. Além disso, você está insatisfeito quando argumenta que uma opção de comando não pode controlar a expansão de curingas feita pelo shell. Claro que não pode! Nem Random832, nem Thanatos, nem Anne van Rossum, e nem mesmo a pergunta em si menciona caracteres curinga de forma alguma. A objeção era que essa ls --only-directories .opção poderia ser adicionada lseventualmente.
Mkalkov 7/08
30

Você pode usar ls -d */ou ls -d .*/para diretórios ocultos.

Jin
fonte
truque inteligente usando o /!
Mono
Sim, isso é bom. Existe algum caso em que isso não funcione?
iyrin
5
+1 por fornecer a resposta em uma linha. Eu acho que a resposta aceita também tem, em algum lugar.
Calculus Knight,
Como você pode usar isso em um script sem já estar no diretório?
DimiDak
13

Tente isto

 find . -mindepth 1 -maxdepth 1 -type d

para obter apenas diretórios em sua localização atual.

ztank1013
fonte
5

você pode gostar também

tree -d 

que lista todos os diretórios e subdiretórios com uma representação gráfica da estrutura da árvore.

fuenfundachtzig
fonte
3
E para apenas um nível profundo:tree -dL 1
Anne van Rossum
Infelizmente você não pode combinar muito com a árvore. # árvore -d | grep wc -l (entrada padrão)
DimiDak 15/02
5

Se você deseja ver os diretórios apenas com a opção de detalhes como ls -l(ELL), pode usar abaixo:

find -maxdepth 1 -type d -ls;

Acima, você fornecerá apenas os detalhes da -lopção.

Adnan Bhatti
fonte
1
Pode ser ainda melhor usar find -maxdepth 1 -type d -exec ls -d {} +para obter a saída no lsformato usual .
Mkalkov 7/08
4

Se você deseja concluir o trabalho de outra maneira, tente o seguinte:

ls -l | grep ^d

Embora uma única ferramenta seja suficiente nessa situação. A linha de tubulação está sempre lá para ajudá-lo. Eu gosto da flexibilidade no Linux, o que desejo que você faça.

Bohr
fonte
1
Isso vai filtrar mais do que diretórios.
Ocodo 01/09
2
@ Slomojo, isso filtrará tudo, exceto os diretórios. O que você quis dizer?
Mkalkov 7/08
Sim, você precisa de -l (long) para que as permissões encabeçam a linha. "d" para o diretório. Além disso, você obtém uma lista "longa" de uma entrada de diretório, o que é legal.
geoO
1

Espero que isso retifique sua necessidade. O comando abaixo listará apenas diretórios em um determinado caminho.

ls -F <path> | grep /

Exemplo:

ls -F ~ | grep /
Thiyagu ATR
fonte