Is there a way to get ls to show all dot files including hidden directories first then regular directories then regular files? I have read throughout the ls man page but come up with nothing. I have also searched Super user and although there are some answers to different questions like showing hidden files first or directories first, I haven't found anything quite in this order. Thanks
2 Answers
I'm going to answer my own question. After more research I have found a way to get what I want.
Although not the exact order in which I initially wanted in the question, I have found a way to do this with the order: All dirs including hidden, then all dot files then all regualr files. With this in .bashrc: alias d='LC_COLLATE=C ls -la --group-directories-first'. And I'm happy with that.
The simplest answer is to split it into two commands: this is best done in a script (such as lssort
), but if you want ls
always to work this way you can alias ls=lssort
:-
ls -d --group-directories-first "$@"/.*
ls -d --group-directories-first "$@"/*
This assumes that a single directory name (which may contain spaces) is given and that it is the last parameter passed. Unfortunately this has two limitations:-
- The directory must be given: to overcome this you need to scan the parameters to find the last and make different calls if the last parameter is an option or doesn't exist (replace
/
by space in the above calls). - If the
ls
options cause a total line (eg-l
) to be output you will get two totals, one for each call.
The first of these is answered by scripting:-
[ $# == 0 ] && lp='' || eval lp="\${$#}"
[ "${lp#-}" == "$lp" ] && sl=/ || sl=' '
ls -d --group-directories-first "$@"$sl.*
ls -d --group-directories-first "$@"$sl*
The second requires all the files to be listed in a single command and the output redirected to a temporary file with a succession of grep
searches, first for ^total [0-9]*$
, then for files beginning with .
, then the same search with -v
to list the remainder. Thus is easy if ls
produces bare file names, but much more complex in the general case, beyond the scope of this answer.
Notes:-
ls -d
is needed to avoid the expansion of subdirectories.... && ... || ...
is a more compact form ofif ...; then ...; else ...; fi
.eval
was necessary to makebash
parse the command line twice:${$#}
gives an error.