Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The Windows dir directory listing command has a line at the end showing the total amount of space taken up by the files listed. For example, dir *.exe shows all the .exe files in the current directory, their sizes, and the sum total of their sizes. I'd love to have similar functionality with my dir alias in bash, but I'm not sure exactly how to go about it.

Currently, I have alias dir='ls -FaGl' in my .bash_profile, showing

drwxr-x---+  24 mattdmo  4096 Mar 14 16:35 ./
drwxr-x--x. 256 root    12288 Apr  8 21:29 ../
-rw-------    1 mattdmo 13795 Apr  4 17:52 .bash_history
-rw-r--r--    1 mattdmo    18 May 10  2012 .bash_logout
-rw-r--r--    1 mattdmo   395 Dec  9 17:33 .bash_profile
-rw-r--r--    1 mattdmo   176 May 10  2012 .bash_profile~
-rw-r--r--    1 mattdmo   411 Dec  9 17:33 .bashrc
-rw-r--r--    1 mattdmo   124 May 10  2012 .bashrc~
drwx------    2 mattdmo  4096 Mar 24 20:03 bin/
drwxrwxr-x    2 mattdmo  4096 Mar 11 16:29 download/

for example. Taking the answers from this question:

dir | awk '{ total += $4 }; END { print total }'

which gives me the total, but doesn't print the directory listing itself. Is there a way to alter this into a one-liner or shell script so I can pass any ls arguments I want to dir and get a full listing plus sum total? For example, I'd like to run dir -R *.jpg *.tif to get the listing and total size of those file types in all subdirectories. Ideally, it would be great if I could get the size of each subdirectory, but this isn't essential.

share|improve this question
Why does't ls -lh help you ? It prints total sum in top. You can also run du -sh *.exe to get disk space usage information in human readable form. – Naai Sekar Apr 16 '13 at 19:40
@ashwin I don't know what the 'total' ls -lh is printing, but it's not always related to what the awk scripts below calculate, or what I add up by hand. Sometimes it's close to the number of KB of files in the directory, but it doesn't seem to take the allocated sizes of subdirectories into effect. I'd be grateful if you could point me toward an explanation of what exactly that number is... – MattDMo Apr 17 '13 at 17:05
see if my answer below works for you – Naai Sekar Apr 17 '13 at 20:17

11 Answers 11

up vote 14 down vote accepted

The following function does most of what you're asking for:

dir () { ls -FaGl "${@}" | awk '{ total += $4; print }; END { print total }'; }

... but it won't give you what you're asking for from dir -R *.jpg *.tif, because that's not how ls -R works. You might want to play around with the find utility for that.

share|improve this answer

There's already a UNIX command for this: du

Just do:

du -h 

As per convention you can add one or more file or directory paths at the end of the command. -h is an extension to convert the size into a human-friendly format.

share|improve this answer
Does du work with file filters like *.exe, *.jpg etcetera – vfclists Aug 30 '13 at 15:36
Yes, du works fine. You can use the -c option (same as --total) to get a total at the end of the list. – MikeB May 21 '14 at 16:28
Note that du gives the disk usage, not the sum of file sizes. – Stéphane Chazelas Feb 9 '15 at 10:41
The reason I haven't chosen this as the answer (although du is a very useful command) is because I want to maintain the basic functionality of ls -l - listing the contents of a directory, only recursively if I ask, and showing the size of each file, which du does not do. Thank you for the answer, though! – MattDMo Feb 12 '15 at 17:59
du -h doesn't sum the sizes of the files passed to it. du -h *.so shows the size of each file, but not the sum. I think what you're wanting here is du -hc *.so (or even du -hc *.so | tail -1). But of course, he wants the directory listing, too. – Limited Atonement Jan 15 at 17:10

Simply print the current line that you are summing the total of:

dir | awk '{ print; total += $4 }; END { print "total size: ",total }'
share|improve this answer

You can use du -h -c directory|tail -1

This will generate a single line with memory usage.

share|improve this answer
du -hs directory if you only want the total. – Stéphane Chazelas Feb 9 '15 at 10:41

with perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

Size of all non-hidden PDF files in current directory.

share|improve this answer

Adding the following to .bash_profile or .bashrc works for me.

dir ()
find . -iname "$@" -exec ls -lh {} \;
find . -iname "$@" -print0|xargs -r0 du -csh|tail -n 1;

Now when i do a dir *.mp3 it does recursively and prints total at the end. You can control how much depth you want by adding a maxdepth parameter to the find. I know running find twice is not a very effiecnt idea. But i couldnt think of a better way. Atleast it gets the job done.

share|improve this answer

Using du and a awk statement like the one mentioned above will provide what you are looking for.

Example: du /home/abc/Downloads/*.jpg | awk '{ print; total += $1 }; END { print "total size: ",total }'

This will list all files in folder Downloads of user abc ending in .jpg and prints the sum of all these files at the end of the listing.

share|improve this answer

To get both, dir output and size calculation, without using any of the other proposed options, you can use tee(1) and process substitution...

dir | tee >( awk '{ total += $4 }; END { print total }' )
share|improve this answer
No need for tee, just dir | awk '{print; total += $4}; END {print total}' – Stéphane Chazelas Feb 9 '15 at 13:27

Just do this:

du -shcl /directory/*
share|improve this answer
Just giving a command is not enough as an answer. – peterh Feb 19 '15 at 8:34
No, if you read the question, you'll see this is not what I want. – MattDMo Feb 19 '15 at 15:21
du * | awk -v sum=0 '{print sum+=$1}' | tail -1
share|improve this answer
This doesn't do what I was asking for. – MattDMo Jun 3 '15 at 21:24
du path_to_your_files/*.jpg | awk '{ total += $1 }; END { print total }'
share|improve this answer
No. First, just giving a command is not an answer. Second, if you'd bothered to read the whole question, the other answers, and my comments, you'd have seen this is NOT what I want. – MattDMo Aug 26 '15 at 18:36

protected by Michael Mrozek Aug 26 '15 at 19:15

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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