Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I would like to use ls command to first show direcotries and then files. I tried

ls -la | sort -k 1

But I got a wrong order.

share|improve this question
    
it's because - comes before d when using sort –  Nifle Feb 16 '10 at 13:32
1  
Old time unix heads (the ones from the pre-GUI age) used to capitalize their folder names and make plain-file names uncapitalized to get that result automagically. –  JRobert Jun 18 '12 at 17:43

9 Answers 9

up vote 11 down vote accepted

The following command will list directories first, ordinary files second, and links third.

ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep "^l"

Also, it would make a great deal of sense to create an alias for this command to save keystrokes.

Edit:

If you want directories first, and then everything that is not a directory second, use this:

ls -la | grep "^d" && ls -la | grep -v "^d"

share|improve this answer
    
This command doesn't list everything if there are, for example, sockets or FIFOs in the folder –  Studer Feb 16 '10 at 14:01
1  
That edited version should still work with other types. The first grep says everything that starts with a 'd', and the second says everything that doesn't start with a 'd'. Surely everything either starts with a d or doesn't, right? –  Ry4an Aug 24 '12 at 12:58
    
To make the first one show other files too: ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep -E "^d|^-" -v | grep -v "^total" –  Mark Apr 26 '13 at 22:25
    
@Mark -- Why not just do: ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep -v -E "^d|^-|^total"? –  FCTW Aug 19 '13 at 3:22
    
To pipe &&-divided commands to less: cat <(ls -la | grep "^d") <(ls -la | grep -v "^d") | less -r –  Andrey Rybak Jun 2 at 13:57

I do so love *nix and love seeing the inventiveness that goes into some of these replies...

Mine's not nearly as fancy on GNU Linux :

alias ls='ls --color -h --group-directories-first'
share|improve this answer
3  
unfortunately, this doesn't work on osx terminal, since -- option is not available. –  MEM May 20 '12 at 13:30
5  
re love: Is that sarcasm? If so, I'd agree. –  allyourcode Jun 2 '12 at 1:06
    
great :) didn't know about the "alias" command :) –  Alex Oct 13 '12 at 14:55
1  
Re: Doesn't work on mac ... True enough, personally though I generally do a brew install coreutils to override the mac builtins for my local user. –  delerious010 Apr 6 at 15:17
    
Why alias ls? Why are we aliasing an already-existing command, and isn't typing ls --group-directories-first easy enough? –  Kevin Jul 29 at 23:21

You've got several choices, depending if you want to keep alphabetical order.

You could simply try :

ls -al | sort -k1 -r

or this, to keep alphabetic order for files with the same permissions :

ls -al | sort -k1,1 -k9,9 -r

or, as eleven81 said (but this version lists everything) :

ls -la | grep "^d" && ls -la | grep "^-" && ls -al | grep -v "^[d|-]"

share|improve this answer
    
This is a nicer solution IMO. Using several processes and pipes to do sorting instead of piping to sort seems kind of backwards. Especially since ls- al|sort -k1 -r works. What was missing is just the -r flag. –  brice Feb 17 '10 at 13:54

To delerious010's answer, I would add that if you want old-style ordering:

LANG=C ls -la --group-directories-first

(or use LC_ALL or LANGUAGE or LC_COLLATE set to "C").

This will give something similar to:

.
..
DIR
Dir
dir
.hidden
123
UC_FILE
Uc_file
lc_file

Although, if I recall correctly, the hidden dot files originally appeared before the directories.

share|improve this answer

Here's a function to do this (bash or zsh): And... I'm not suggesting this is the best way, but it's the one I came up with and am using right now:

function lss
{
    # Shows directory listing with directories at the top.

    command ls  --color=always $@ | egrep '^d|total'
    command ls  --color=always $@ | egrep -v '^d|total';
}
share|improve this answer

For Mac users:

brew install coreutils

alias ls='gls --color -h --group-directories-first'

Assuming your system is ready to brew

share|improve this answer

Another way ...

find . -d 1 -type d | ls -la | sort -r 

OR

ls -la | sort -r

OR

d=`find . -type d -d 1`;f=`find . -type f -d 1`; echo -e -DIRS- "\n$d\n" -FILES- "\n$f"
share|improve this answer
    
What do these do? Where did you learn to type them? –  Tom Wijsman Jun 11 '12 at 18:31
    
Well My preferred OS is Debian Linux. Debian's gnu core utils package version of ls supports the --show-directories-first option ... when I started using OSX I simply grabbed my all my bash dot files from my Debian box and dropped them in my home directory ... I had a lot of bash_aliases that broke so ... It was then that I had to figure out some work-arounds for my aliases ... –  Eddie B Jun 12 '12 at 1:13
    
The first one is a bit redundant ... There's really no reason to sort for the directories as it's the order we need to modify not directories ... the 'ls -la | sort -r' is what really works. Basically it's stating ... 1) A) Find . -d 1 -type d (Start from this directory, search one directory depth and search for directories only) B) ls -la (list files all attributes) C) Sort them in reverse 2) Do as 1) just drop the find ... it's not needed ... I actually like Studers' solution better ... :-) –  Eddie B Jun 12 '12 at 1:21

ls -laX will show you directories first in alphabetical order, but will screw the file list.

Long options:

ls
    -l    # List
    --all
    -X    # Sort alphabetically by entry extension
share|improve this answer
    
This would only work if you could be absolutely certain that every directory had no dots in its name. –  eleven81 Feb 16 '10 at 13:43

This is a script solution. Lists just the names, no inode data, alphabetical, not case sensitive, formatted into columns. Although it's row-major instead of column major like the default output of ls. The columns get a little messy if there is a file name with >26 characters.

rm -f /tmp/lsout
ls -1p | grep / | sort -f >> /tmp/lsout
ls -1p | grep -v / | sort -f >> /tmp/lsout

IFS=$'\n' read -d '' -r -a lines < /tmp/lsout

printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

And another, with some extra formatting.

rm -f /tmp/lsout
echo "  ---- Directories ---- " >> /tmp/lsout
ls -1p | grep / | sort -f >> /tmp/lsout
IFS=$'\n' read -d '' -r -a lines < /tmp/lsout
printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

rm -f /tmp/lsout
echo "  ------- Files ------- " >> /tmp/lsout
ls -1p | grep -v / | sort -f >> /tmp/lsout
IFS=$'\n' read -d '' -r -a lines < /tmp/lsout
printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

Output for the last one looks like the following, minus the colors:

  ---- Directories ----   archive/                  bookmarks/              
Desktop/                  Documents/                Downloads/              
fff/                      health/                   Library/                
Movies/                   Music/                    Pictures/               
Public/                   rrf/                      scifi/            
testdir/                  testdir2/                                         
  ------- Files -------   @todo                     comedy            
delme                     lll                       maxims                  
schedule                  vtokens style

Just remember not to alias or change the default behavior of ls since this script calls it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.