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.