A resposta mais simples é dividi-la em dois comandos: isso é feito melhor em um script (como lssort
), mas se você quiser que ls
sempre funcione dessa maneira, você pode alias ls=lssort
: -
ls -d --group-directories-first "$@"/.*
ls -d --group-directories-first "$@"/*
Isso pressupõe que um único nome de diretório (que pode conter espaços) seja fornecido e que seja o último parâmetro passado. Infelizmente isso tem duas limitações: -
- O diretório deve ser fornecido: para superar isso, você precisa verificar os parâmetros para encontrar o último e fazer chamadas diferentes se o último parâmetro for uma opção ou não existir (substitua
/
pelo espaço nas chamadas acima) .
- Se as opções
ls
fizerem com que uma linha total (por exemplo, -l
) seja exibida, você obterá dois totais, um para cada chamada.
O primeiro deles é respondido por script: -
[ $# == 0 ] && lp='' || eval lp="\${$#}"
[ "${lp#-}" == "$lp" ] && sl=/ || sl=' '
ls -d --group-directories-first "$@"$sl.*
ls -d --group-directories-first "$@"$sl*
O segundo exige que todos os arquivos sejam listados em um único comando e a saída seja redirecionada para um arquivo temporário com uma sucessão de grep
pesquisas, primeiro para ^total [0-9]*$
, depois para arquivos iniciados com .
, mesma pesquisa com -v
para listar o restante. Portanto, é fácil se ls
produzir nomes de arquivos nus, mas muito mais complexos no caso geral, além do escopo desta resposta.
Notas: -
-
ls -d
é necessário para evitar a expansão de subdiretórios.
-
... && ... || ...
é uma forma mais compacta de if ...; then ...; else ...; fi
.
-
eval
foi necessário para tornar bash
analisar a linha de comando duas vezes: ${$#}
apresenta um erro.