Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

When I type ls, i get the normal list, or when I type ls -la I get a details version with everything...

But I hate the layout of ls, it's just unintuitive for most of my use.

Is there some way I can modify (without changing the sorcecode of ls, bash scripts are okay however) ls so it's display instead of

-rwxr-xr-x 13 user group 123546 2011-01-01 11:11 filename0
-rwxr-xr-x 13 user group 123546 2011-01-01 11:11 filename1
-rwxr-xr-x 13 user group 123546 2011-01-01 11:11 filename2
drwx------ 13 user group 123546 2011-01-01 11:11 directory0
-rwxr-xr-x 13 user group 123546 2011-01-01 11:11 filename3
drwx------ 13 user group 123546 2011-01-01 11:11 directory1

I can get a list more like:

DIRS
directory0 1293880260 700 user:group
directory1 1293880260 700 user:group

FILES
filename0 1293880260 751 user:group
filename1 1293880260 755 user:group
filename2 1293880260 777 user:group
filename3 1293880260 705 user:group

Or some other variation.

Meanwhile, preserving ability to use flags and other options.

share|improve this question
add comment

5 Answers

You could write a bash script called ~/bin/ls that should override /bin/ls. remember to run chmod +x ~/bin/ls.

I've just written this which seems to do most of what you want to accomplish (including passing along extra arguments)

#!/bin/bash

DIRS="`/bin/ls --color=auto -l $@ | grep ^d`"
FILES="`/bin/ls --color=auto -l $@ | grep ^\-`"

if [ "$DIRS" ]
then
    echo "DIRECTORIES"
    echo -e "$DIRS\

"
fi

if [ "$FILES" ]
then
    echo "FILES"
    echo "$FILES\

"
fi

Somebody might want to tidy that up a little or improve the output formatting, but there you go. Yours to do whatever you like with.

And here's some genuine sample output:

ls
DIRECTORIES
drwxr-xr-x 4 oli oli     4096 2010-12-16 15:40 markitup
drwxr-xr-x 7 oli oli     4096 2011-01-16 16:58 media
drwxr-xr-x 3 oli oli     4096 2010-12-16 15:41 post
drwxr-xr-x 9 oli oli     4096 2010-09-16 05:23 templates

FILES
-rw-r--r-- 1 oli oli  5361664 2010-09-06 16:32 db.db
-rw-r--r-- 1 oli oli        0 2008-12-11 09:22 __init__.py
-rwxr-xr-x 1 oli oli      542 2008-12-11 09:22 manage.py
-rw-r--r-- 1 oli oli       13 2010-03-23 18:14 settingsdev.py
-rw-r--r-- 1 oli oli     2642 2010-12-16 15:40 settings.py
-rw-r--r-- 1 oli oli     1818 2010-12-16 15:40 urls.py
-rw-r--r-- 1 oli oli      432 2010-06-22 20:54 views.py

And with arguments:

ls -a
DIRECTORIES
drwxr-xr-x  8 oli oli     4096 2011-01-12 00:46 .
drwxr-xr-x 19 oli oli     4096 2011-04-13 17:24 ..
drwxr-xr-x  6 oli oli     4096 2010-02-03 13:50 .bzr
drwxr-xr-x  4 oli oli     4096 2010-12-16 15:40 markitup
drwxr-xr-x  7 oli oli     4096 2011-01-16 16:58 media
drwxr-xr-x  3 oli oli     4096 2010-12-16 15:41 post
drwxr-xr-x  9 oli oli     4096 2010-09-16 05:23 templates

FILES
-rw-r--r--  1 oli oli       65 2010-03-27 07:58 .bzrignore
-rw-r--r--  1 oli oli  5361664 2010-09-06 16:32 db.db
-rw-r--r--  1 oli oli        0 2008-12-11 09:22 __init__.py
-rwxr-xr-x  1 oli oli      542 2008-12-11 09:22 manage.py
-rw-r--r--  1 oli oli       13 2010-03-23 18:14 settingsdev.py
-rw-r--r--  1 oli oli     2642 2010-12-16 15:40 settings.py
-rw-r--r--  1 oli oli     1818 2010-12-16 15:40 urls.py
-rw-r--r--  1 oli oli      432 2010-06-22 20:54 views.py
share|improve this answer
add comment

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

Shows... directories, normal files, links in that order.

Make it an alias and you are set to go.

Found another method:

ls -l --color -h --group-directories-first

This one does directories first and colors the filenames.

In ~/.bashrc you can create an alias to this command like so:

alias ls1='ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep "^l"

Sample output:

drwxr-xr-x  5 96 2011-05-20 13:41 .
drwxr-xr-x 16 xxxx uuuu 96 2010-03-05 12:34 ..
drwx------  2 xxxx uuuu 96 2009-02-13 14:31 .ssh
drwxrwxr-x  2 xxxx uuuu 96 2009-12-03 13:49 .xxx
drwxrwxr-x  5 xxxx uuuu  96 2010-12-06 15:51 xxxxxx
-rw-------  1 xxxx uuuu  05 2011-05-20 14:12 .bash_history
-rw-r--r--  1 xxxx uuuu  20 2009-02-12 09:33 .bash_logout
-rw-r--r--  1 xxxx uuuu 29 2009-03-06 11:47 .bashrc
-rw-r--r--  1 xxxx uuuu 80 2011-05-20 13:42 fff
-rw-rw-r--  1 xxxx uuuu 03 2011-05-18 10:21 dffff

or for the second one: alias ls2=ls -l --color -h --group-directories-first

Sample output:

drwxrwxr-x 5 xxxx uuuu 4.0K 2010-12-06 15:51 ddddd
-rw-r--r-- 1 xxxx uuuu 339M 2011-05-20 13:42 sssss
-rw-rw-r-- 1 xxxx uuuu 4.6M 2011-05-18 10:21 dxsssss
-rwxrwxr-x 1 xxxx uuuu   68 2011-02-22 15:55 5555
-rwxr--r-- 1 xxxx uuuu  20K 2010-12-06 16:11 ffff
ddddd will be in another color. add -a to also include hidden files.

and you created a command ls1 and ls2 to do this.

share|improve this answer
add comment

Here's my quick jab at it.

$ function lss { ls -l --group-directories-first --time-style +%s $@ | grep -v '^total' | awk 'BEGIN {print("DIRS")} {if (f!=1 && $1 ~ /^-/) {print "\nFILES"; f=1}; printf("%s\t%s %s %s:%s\n", $7, $6, $1, $3, $4);}'; }
$ alias ls='lss'
$ ls
DIRS
directory0  1305901476 drwxr-xr-x ak:ak
directory1  1305901476 drwxr-xr-x ak:ak

FILES
filename0   1305901484 -rw-r--r-- ak:ak
filename1   1305901484 -rw-r--r-- ak:ak
filename2   1305901484 -rw-r--r-- ak:ak
filename3   1305901484 -rw-r--r-- ak:ak

The benefit of this approach is that it does not require multiple directory traversals and prints the output as it is ready. Try running this after touch filename{0..10000} as a test.

Drop the function and alias lines into ~/.bashrc to make it permanent.

Benchmarking from Oli:

oli@bert:~/Desktop$ mkdir test
oli@bert:~/Desktop$ cd test
oli@bert:~/Desktop/test$ mkdir dir{0..100000}
oli@bert:~/Desktop/test$ touch filename{0..100000}

oli@bert:~/Desktop/test$ time /bin/ls>/dev/null

real    0m0.975s
user    0m0.860s
sys         0m0.110s

oli@bert:~/Desktop/test$ time ls --group-directories-first -l >/dev/null

real    0m1.810s
user    0m1.210s
sys         0m0.580s


oli@bert:~/Desktop/test$ time lss>/dev/null  # ændrük's method

real    0m2.035s
user    0m1.810s
sys         0m0.780s

oli@bert:~/Desktop/test$ time ~/bin/ls>/dev/null  # Oli's method

real    0m5.496s
user    0m4.290s
sys         0m1.460s
share|improve this answer
2  
Added some benchmarking to your post (as you mentioned it). Yeah over 100,000 directories and 100,000 files, yours takes less than half the time. But ls on its own is still a lot faster. Either way, this is a edge case. Most people never have such huge directory listings. For normal people, there's little observable difference. Nice awking though. +1 –  Oli May 20 '11 at 15:25
add comment

ls doesn't support much output customization.

Use

 ls --group-directories-first -l

to just get the dirs first.

Have a look at limo (not installed by default) for an alternative to ls that supports more output customization (but doesn't support all the options of ls)

share|improve this answer
add comment

Extending the alias settings in .bashrc is my prefered way of getting more convenient 'ls' commands. I like especially the 'lf' (requires installation of 'tree').

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias lf='tree -d -L 1'
share|improve this answer
add comment

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.