How can I make "ls" show dotfiles first?
Solution 1
⚠️ This answer is a little dated. Please check out the other answers, particularly those using aliases or
ls -v
.
Try adding
export LC_COLLATE="C"
in your dotfiles, or changing the LC_ALL
assignment to:
export LC_ALL="C"
This controls the way sorting on character level works — while the default would be to sort dotfiles inline, this will make sort
list dotfiles first.
However, note that this will basically stop support for your actual locale across all locale-aware utilities.
To go further, quoting the GNU Coreutils manual (emphasis mine):
If you use a non-POSIX locale (e.g., by setting
LC_ALL
toen_US
), then sort may produce output that is sorted differently than you're accustomed to.In that case, set the
LC_ALL
environment variable toC
. Note that setting onlyLC_COLLATE
has two problems. First, it is ineffective ifLC_ALL
is also set. Second, it has undefined behavior ifLC_CTYPE
(orLANG
, ifLC_CTYPE
is unset) is set to an incompatible value. For example, you get undefined behavior ifLC_CTYPE
isja_JP.PCK
butLC_COLLATE
isen_US.UTF-8
.
Solution 2
To avoid any system wide changes without real need, one can change only the way how ls
works for the current user by adding the alias to the .bashrc
:
alias ll='LC_COLLATE=C ls -alF'
This sorts dot files first, allows to properly handle (show and sort) "uncommon" character sets like cyrillic. The only culprit that the sorting will be case-sensitive.
Source: http://ubuntuforums.org/showthread.php?t=816753
Solution 3
The ls(1) manpage lists:
-v natural sort of (version) numbers within text
This seems change how periods are sorted and does group dotfiles first. I have:
alias ls='ls -vAF'
alias ll='ls -l'
in my ~/.bashrc.
Solution 4
Setting
LC_ALL="C.UTF-8"
works fine for me - umlauts and "ls -la" lists dot-files first.
Solution 5
An off the wall idea
Disclaimer: This is going to be overkill for most of you. But I've been doing this since 1995 and I have the skills to make my world exactly how I want it. So, I why not?
I really like using different sorting methods with ls
, especially -rt
(which is sort by r
everse modified t
ime). So, I decided to try something crazy and use awk to do my sorting.
# save as ~/.ls.awk
# inpsired by http://superuser.com/questions/448291/how-can-i-make-ls-show-dotfiles-first
{
if($1 == "total"){
print $0
next
}
# may need to adjust $9 to match your name column
if(match($9, /^(\033\[[0-9]*m)*\./)) # optionally look past xterm highlighting like: ^[[34m
df[++dd] = $0
else
nf[++nn] = $0
}
END{
while (++d in df)
print df[d]
while (++n in nf)
print nf[n]
}
Now instead of defining a bash alias, I define a bash function (because aliases can only append arguments at the end, but functions can use them anywhere)
ll(){ CLICOLOR_FORCE=1 ls -lhA $* | awk -f ~/.ls.awk; }
To see the results
Let's create some sample files:
for n in 4 .4 3 .3 2 .2 1 .1; do touch $n; sleep 1; done
Using plain ls
$ ls -lA
total 8
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .1
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .2
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .3
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .4
-rwxr-xr-x 1 bbronosky staff 285 Nov 29 13:14 .ls.awk
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 1
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 2
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 3
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 4
$ ls -lArt
total 8
-rwxr-xr-x 1 bbronosky staff 285 Nov 29 13:14 .ls.awk
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 4
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .4
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 3
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .3
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 2
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .2
-rwxr-xr-x 1 bbronosky staff 0 Dec 1 00:25 1
-rw-r--r-- 1 bbronosky staff 0 Dec 1 00:25 .1
Using my function that filters with awk
$ ll
total 8
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .1
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .2
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .3
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .4
-rwxr-xr-x 1 bbronosky staff 285B Nov 29 13:14 .ls.awk
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 1
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 2
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 3
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 4
$ ll -rt
total 8
-rwxr-xr-x 1 bbronosky staff 285B Nov 29 13:14 .ls.awk
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .4
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .3
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .2
-rw-r--r-- 1 bbronosky staff 0B Dec 1 00:25 .1
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 4
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 3
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 2
-rwxr-xr-x 1 bbronosky staff 0B Dec 1 00:25 1
You can see my implementation of this here https://github.com/RichardBronosky/dotfiles/commit/6170c0a9
What's most important about this is that it is a framework for tweaking your ls
output. You can do anything you want with that awk filter. You might want it to be directories, then dotfiles, then everything else. Once you know how to handle your xterm colors, it's not too difficult. It's totally up to you.
Related videos on Youtube
clang1234
Updated on September 18, 2022Comments
-
clang1234 almost 2 years
Somewhere along the way I screwed up my ls command and now I get this ordering when running
$ ls -AhHl --color=auto -rwxr-xr-x 1 clang clang 640 Mar 1 02:46 apple-touch-icon-precomposed.png -rwxr-xr-x 1 clang clang 784 Jul 12 02:54 crossdomain.xml -rwxr-xr-x 1 clang clang 1.2K Mar 1 02:46 favicon.ico drwxr-xr-x 8 clang clang 4.0K Jul 12 23:50 .git -rw-r--r-- 1 clang clang 17 Feb 29 19:48 .gitignore -rwxr-xr-x 1 clang clang 1.4K Jul 12 02:54 humans.txt
What did I do that made ls ignore the dotfiles and instead order by first letter?
Output of
locale
:$ locale LANG= LANGUAGE= LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_PAPER="en_US.UTF-8" LC_NAME="en_US.UTF-8" LC_ADDRESS="en_US.UTF-8" LC_TELEPHONE="en_US.UTF-8" LC_MEASUREMENT="en_US.UTF-8" LC_IDENTIFICATION="en_US.UTF-8" LC_ALL=en_US.UTF-8
-
clang1234 almost 12 yearsSetting LC_ALL="C" did the trick! Thanks for the quick response
-
ohho almost 11 yearsSetting LC_ALL="C" will
ls
foreign language (e.g. Japanese) unicode filenames as????????
-
Chnossos almost 10 yearsdot files are listed first, but now file names that starts with a uppercase letter are listed before those that starts with a lowercase.
-
mklement0 over 9 yearsNote that by adding
export LC_ALL="C"
to your dotfiles you'll effectively lose support for your actual locale across all locale-aware utilities. While the printing problem that @ohho points out could be remedied with Faroul's answer, you'll introduce sorting problems: sorting will happen by byte value only, resulting in sorting that is (a) unexpectedly case-sensitive, and (b) invariably places accented chars. after all non-accented ones. -
mklement0 over 9 years+1 for coming closer than the accepted answer, but to summarize the limitations: the sorting will become case-sensitive, and foreign characters - while now printed correctly due to
UTF-8
- won't be sorted correctly. -
Software Engineer about 9 yearsThis is the best answer here by far
-
Martin Tournoij about 9 years
C.UTF-8
is an invalid locale, so locale reverts back toC
. You still lose UTF-8 support. In fact, it's even worse sinceLC_ALL=C
mostprograms display most multibyte characters correctly, but withLC_ALL=something_invalid
some programs don't (like `ls). -
Gui Ambros about 8 yearsBeautiful. Much better than changing the system-wide configuration (which can cause you problems with some python modules).
-
matty almost 8 yearsThis was the most helpful answer. Additionally, in an environment where
LC_ALL
is already set to something incompatible with sorting/hoisting dotfiles to the top of thels
listing, usealias ll='LC_ALL=C ls -alF'
instead, becauseLC_COLLATE
doesn't overrideLC_ALL
. -
G-Man Says 'Reinstate Monica' over 6 yearsWhat does
--group-directories-first
have to do with “show dotfiles first”? -
muru almost 6 years@MartinTournoij but if Stéphane Chazelas says otherwise about GNU systems (so presumably Debian and Linux in general), which is correct?
-
Martin Tournoij almost 6 years@muru I'm not sure, I guess you'll have to ask Stéphane? All I know is that
locale
seems to error out withLC_ALL=C.UTF-8
: gist.github.com/Carpetsmoker/ef09b3734b29372939f97107413d7733 – that is on Arch Linux. -
muru almost 6 years@MartinTournoij seems it's not enabled on Arch: bugs.archlinux.org/task/32296 (it is on Debian and co, and Fedora as well: bugzilla.redhat.com/show_bug.cgi?id=902094)
-
Martin Tournoij almost 6 years@muru Looks like they included a custom patch against GNU libc, so it's something that may or may not work depending on your Linux/Unix flavour and libc that's being used.
-
Odaya G about 5 years+1 for being creative. Did not work though.
-
George Hawkins about 4 yearsI think this answer is a little out of date. At the very least use
C.UTF-8
, as in @Faroul's answer, as the old non-Unicode variant will cause trouble for things like Python 3 output. But do note, as others have, that locale affects everything, not justls
, so setting the locale toC
orC.UTF-8
will e.g. disable spell checking. So best to set your locale appropriately, e.g. toen_US.UTF-8
, and go for a solution that only affectsls
(like using aliases and the-v
flag as in @VinceValenti's answer). -
Luke almost 4 yearsthank you very much for
ls -v
-
Luke almost 3 yearsthanks for
ls -v