1

Is there any ls parameter which I can use to display file-size for directories as well.

When I do ls -s, it shows me block-size(4k always) instead of directory size.

Thank you!!!

Edit - Partial achievement

As told by @Arronical, Command du -sh * shows the files & directories with their size. One small enhancement I am looking is to show directory in different colour like ls shows. Any ideas. Thank you. :-)

3 Answers3

6

I'm not aware of any parameters for the ls command which can achieve this, but it is possible to find the sizes of the directories and files in the present working directory with the du command.

Try using:

du -sh ./*

It should be possible to create a function or a script which gives you information as to whether it's a file or directory for which information is being displayed.

As muru pointed out, the -d or --max-depth option, with a parameter of 1, would be useful for listing just directories. It also works around the fact that hidden directories are not listed by normal shell globbing (the ./* part).

Arronical
  • 19,893
5

Basic idea

One could emulate the ls -l with find. For instance, like with find command that will run du per each directory and file found:

find . -maxdepth 1  ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 

Sample output ( side note , here I am using -type d to show listing for directories only for demo purpose; this command without -type d will list all files and directories):

DIR:/xieerqi
skolodya@ubuntu:$ find . -maxdepth 1 -type d ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null | head      
drwxrwxr-x xieerqi xieerqi 348K ./addRemoveDistribution
drwxr-xr-x xieerqi xieerqi 2.2G ./Downloads
drwxrwxr-x xieerqi xieerqi 4.0K ./.screenlayout
drwxr-xr-x xieerqi xieerqi 4.0K ./Public
drwxrwxr-x xieerqi xieerqi 28K  ./Youku Files
drwxrwxr-x xieerqi xieerqi 142M ./.minecraft
drwx------ xieerqi xieerqi 20K  ./.gnupg
drwxrwxr-x xieerqi xieerqi 2.5G ./.Genymobile
drwxrwxr-x xieerqi xieerqi 73M  ./genymotion
drwxrwxr-x xieerqi xieerqi 104K ./scripts

NOTE: find has -ls flag, which I am not using here, for the same reason as OP stated - it shows canonical 4096 bytes

Simplification

This command itself can be turned into an alias, something like ls2 or a function, which then also could take $1 argument. For instance, here's what I've placed into my .bashrc and how it works:

function lscwd
{
 # Function to stat files and folders in current dir
 # Takes first argument as directory to stat
 # If no directory supplied, current dir assumed
 if [ -z "$1" ];then
   DIR="."
 else
   DIR="$1"
 fi

 find "$DIR"  -maxdepth 1 ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 

}

Sample runs:

DIR:/xieerqi
skolodya@ubuntu:$ lsc
lscpu lscwd 
skolodya@ubuntu:$ lscwd | head                                                                                               
drwxrwxr-x xieerqi xieerqi 348K ./addRemoveDistribution
drwxr-xr-x xieerqi xieerqi 2.2G ./Downloads
drwxrwxr-x xieerqi xieerqi 4.0K ./.screenlayout
drwxr-xr-x xieerqi xieerqi 4.0K ./Public
drwxrwxr-x xieerqi xieerqi 28K  ./Youku Files
drwxrwxr-x xieerqi xieerqi 142M ./.minecraft
drwx------ xieerqi xieerqi 20K  ./.gnupg
drwxrwxr-x xieerqi xieerqi 2.5G ./.Genymobile
drwxrwxr-x xieerqi xieerqi 73M  ./genymotion
drwxrwxr-x xieerqi xieerqi 104K ./scripts

DIR:/xieerqi
skolodya@ubuntu:$ lscwd /etc | head                                                                                          
drwxr-xr-x root root 18M    /etc
drwxr-xr-x root root 68K    /etc/logrotate.d
drwxr-xr-x root root 36K    /etc/apm
drwxr-xr-x root root 96K    /etc/speech-dispatcher
drwxr-xr-x root root 28K    /etc/jwm
drwxr-xr-x root root 8.0K   /etc/hp
drwxr-xr-x root root 8.0K   /etc/gtk-2.0
drwxr-xr-x root root 20K    /etc/gtkmathview
drwxr-xr-x root root 68K    /etc/xml
drwxr-xr-x root root 8.0K   /etc/esound

Output organization

There's no way to colorize the output natively in find, which is designed specifically to parse filenames. ls coloring comes from special characters included into the output, which we don't really want.

However, one could read the permissions. The leading - in -rwxr-xr-x means it's a regular file, and leading d in drwxr-xr-x means directory.

find also has the handy -type flag, which we can use as well to filter the output. For instance, here's edited version of lscwd

function lscwd2
{
 # Function to stat files and folders in current dir
 # Takes first argument as directory to stat
 # If no directory supplied, current dir assumed
 if [ -z "$1" ];then
   DIR="."
 else
   DIR="$1"
 fi

 # print directories first
 printf "*** DIRECTORIES *** \n"
 find "$DIR"  -maxdepth 1 -type d ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 
 # print non-directories second
 printf "*** FILES *** \n"

 find "$DIR"  -maxdepth 1 ! -type d ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 
 }

And sample output:

DIR:/bin
skolodya@ubuntu:$ lscwd2
*** DIRECTORIES *** 
drwxrwxr-x xieerqi xieerqi 4.0K ./c
drwxrwxr-x xieerqi xieerqi 12K  ./python
drwxrwxr-x xieerqi xieerqi 12K  ./perl
drwxrwxr-x xieerqi xieerqi 4.0K ./ANOTHERDIR
drwxrwxr-x xieerqi xieerqi 4.0K ./random
drwxrwxr-x xieerqi xieerqi 108K ./sh
drwxrwxr-x xieerqi xieerqi 38M  ./cs2
drwxr-xr-x xieerqi xieerqi 414M ./arduino-1.6.7
drwxrwxr-x xieerqi xieerqi 24K  ./codereview
*** FILES *** 
-rwxrwxr-x xieerqi xieerqi 4.0K ./preventShutdown.sh
-rw-rw-r-- xieerqi xieerqi 4.0K ./Dimmer.desktop
-rwxrwxr-x xieerqi xieerqi 4.0K ./updateWarning.sh
-rw-rw-r-- xieerqi xieerqi 4.0K ./somefile.txt
-rw-r--r-- xieerqi xieerqi 4.0K ./.bashrc
-rwxr-xr-x xieerqi xieerqi 4.0K ./setup.sh
-rwxrwxr-x xieerqi xieerqi 4.0K ./whiledemo.csh
-rwxr-xr-x xieerqi xieerqi 4.0K ./fmtcode.awk
-rwxrwxr-x xieerqi xieerqi 4.0K ./batmon.sh
-rwxr-xr-x xieerqi xieerqi 4.0K ./Dimmer.sh
-rw-rw-r-- xieerqi xieerqi 4.0K ./somefile2.txt

The output sometimes can be very lengthy , so I would suggest using this function in conjunction with less paging utility. Just pipe the output like so lscwd2 | less

About ls and stat

Why do people always suggest du ? izx in his brief and awesome answer explained it way better that I could, but in a nutshell, on Unix and Linux everything is a file, and in the reality directory is a file with a list of files linked to it. Thus, stat and ls give size of that special file, not the total amount of all the files linked to the directory. But du is what saves the day. Note what the description in man du says :

Summarize disk usage of each FILE, recursively for directories.

du utility jumps down into each directory and sums up file size of each file there. Way different from what ls and stat do.

So the purpose of each utility is very different. ls is doing exactly what it is asked to do - list file sizes, and coming from Windows world we understand directory's size as being this "bag" whose size depends on the amount of apples in it, if I may use it for comparison. Unix is slightly different, yes, but it is realistic. Maybe it doesn't cater to user needs that much, but it makes sense in real, physical sense.

On a side note, block size is by default 4k, but once file grows over 4k, the filesystem will need to allocate more space. For instance, my home folder has 73GB in total size of all files there. What about the block size of the directory ?

DIR:/bin
skolodya@ubuntu:$ ls -ld $HOME
drwxr-xr-x 94 xieerqi xieerqi 16384 Jan 22 07:24 /home/xieerqi/
Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • This one is perfect. Exactly what I am looking for. Thanks a lot serg. Any idea why during print out, there is ./ printed before all files and dir's. Any possibility of colored output for directories? – We are Borg Jan 22 '16 at 08:06
  • I just added your script in .bashrc and it works awesome. Thank you. Just one thing, I had also added the cowsay program which will show its output when terminal is opened, but it's not working. Any idea? Here is the entire .bashrc(please have a look at bottom) : http://pastebin.com/D3U96HLP – We are Borg Jan 22 '16 at 08:14
  • Nice! I'd been playing with doing this in find, but had no idea about the useful stuff that -printf could do. – Arronical Jan 22 '16 at 09:24
  • There are ways to colorize output, but it is way to troublesome . The find utility is specifically designed to ease operating on filenames without containing extra invisible garbage characters, which by the way is what contains in the output of ls. I will be making an extensive edit of my answer, where I'll explain everything in much detail. I'll post a comment when ready – Sergiy Kolodyazhnyy Jan 22 '16 at 14:17
  • done editing. Please review – Sergiy Kolodyazhnyy Jan 22 '16 at 15:00
  • @WeareBorg by the way, function definition should be at the top of the .bashrc file. Calls to individual commands are better to be put at the bottom – Sergiy Kolodyazhnyy Jan 22 '16 at 15:06
  • Yes, this looks awesome. Thanks a lot.. :-) So unfortunate that official ls tool doesn't have something like this. Now that directories are named separately, it is fine. As per your recommendation, I moved the function on top. Thanks again. :-) – We are Borg Jan 22 '16 at 15:10
  • What do you mean by : What about the block size of the directory ? – We are Borg Jan 22 '16 at 15:11
  • @WeareBorg When I said "What about the block size of the directory? " I meant "Lets take a look at the size of my home directory file ", because like I have mentioned in my answer , everything on linux is file, so once that list file grows , there's more and more files listed inside directory, the size of that list will grow too, and will be reported over 4k by ls . As for "official" ls there's nothing wrong with it, it's just big difference from how Windows make people think, to how computer science actually works :) – Sergiy Kolodyazhnyy Jan 22 '16 at 15:16
  • Yes... That's normal. I thought it had some connection to this, so enquired. Fortunately, I am on a SSD of 120gb, not that much worried about block-size at this point of time. :-) – We are Borg Jan 22 '16 at 15:18
  • Block size has nothing to do with SSD vs HDD, the filesystem will still make data into chunks, for instance bc <<< "$(cat /sys/class/block/sda1/size)*512" will tell you that sda1 partition is in fact using 512MB chunks. And if we multiply number of chunks by 512 MB per chunk, we know total partition size :) – Sergiy Kolodyazhnyy Jan 22 '16 at 15:22
2

Parsing the output of ls always leads to grief. See this explanation. Use stat (man stat) instead.

from man stat:

NAME
       stat - display file or file system status

SYNOPSIS
       stat [OPTION]... FILE...

DESCRIPTION
       Display file or file system status.
...

       %b     number of blocks allocated (see %B)

       %B     the size in bytes of each block reported by %b
...
       %n     file name

And an example on my system YMMV:

$ stat --format="%n %b %B" .bashrc $HOME
.bashrc 32 512
/home/w3 192 512
waltinator
  • 36,399
  • waltinator, while I 100% agree with you and know well from experience your answer is true, you should improve your answer with examples of stat usage , also include explanation or at least a pointer to more info on dangers of parsing ls. In addition , verify that stat can in fact show directory size instead of canonical 4096 bytes – Sergiy Kolodyazhnyy Jan 21 '16 at 19:55