ls: exibe o nome do diretório quando apenas um corresponde ao padrão

ls: exibe o nome do diretório quando apenas um corresponde ao padrão

Ao usar lspara exibir arquivos que correspondem a um padrão, ele exibe os nomes dos diretórios com conteúdo se houver várias correspondências, mas se houver apenas uma correspondência, ele omite o nome do diretório. Aqui está um exemplo:

example % ls
bar     barbados    foo

example % ls b*
bar:
1   2

barbados:
1   2

example % ls f*
1   2

No exemplo, a solicitação de todos os arquivos que começam com b*corresponde a dois diretórios e a saída mostra os nomes de ambos os diretórios e seu conteúdo.

Quando solicito, f*a saída mostra o conteúdo do único diretório correspondente, mas omite o nome do diretório.

Como posso configurar lspara exibir o nome do diretório correspondente caso ele corresponda apenas a um único diretório?

Responder1

A possível solução alternativa pode ser uma função wrapper:

dls() {
    if [ "$#" -eq 1 ] && [ -d "$1" ]; then
        printf '%s:\n' "$1"
    fi
    ls -- "$@"
}
  • A função acima não aceitará nenhuma opção a ser passada como argumento
  • Ele simplesmente verifica se:
    1. há apenas um único argumento
    2. o argumento é um diretório

Se essas duas condições forem verdadeiras, imprima o nome do diretório antes de listar seu conteúdo.


% dls f*
foo:
1   2

Com algumas printfimplementações, você pode substituir o %spor %qpara que o nome do diretório seja citado de maneira semelhante às versões recentes do GNU lsquando contém espaços em branco ou outros caracteres especiais.

Responder2

Usando seus exemplos, quando você executa ls b*, o shell expande b*into bar barbados, então você realmente executa ls bar barbados. Quando lspossui vários argumentos, se algum deles for diretórios ele imprime o nome seguido da lista de arquivos do diretório.

Quando você executa ls f*, o shell expande f*into foo, então você realmente executa ls foo. Quando lstem um único argumento, se esse argumento for um diretório, imprime a lista de arquivos no diretório (sem o nome do diretório).

Não existe o que eu chamaria de uma maneira "boa" de fazer lso que você deseja (pelo menos não que eu saiba, alguém pode saber melhor). Uma maneira "menos que boa" seria incluir um argumento adicional que você sabe que nunca existiria e, em seguida, filtrar a saída de erro relacionada a esse arquivo inexistente. Observo, para constar, que analisar a saída de lsé uma má ideia, mas darei isso caso ajude:

$ function dls() {
    if [[ $# -eq 0 ]]; then
        ls
    else
        ls ${@} this-file-does-not-exist-anywhere 2> >(grep -v this-file-does-not-exist-anywhere)
    fi
}

$ dls
foo

$ dls f*
foo:
1  2

Fazer algo assim pode ter consequências indesejadas (por exemplo, talvez você não consiga redirecionar mensagens de erro padrão como faria normalmente).

Responder3

Use o -alparâmetro que a maioria das pessoas usa sempre. lsnão fará isso até que você adicione uma barra final ao nome do diretório. O outro parâmetro é -d, então não descerá de forma alguma.

Se você quiser que seja permanente, coloque o seguinte em .bashrcseu diretório inicial:

alias lsd='ls -d' ;

Você pode usar o comando lsdno futuro.

informação relacionada