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

how to scan a folder recursively and find the largest files in the folder, and sort them by size. I have tried using ls -R -S but it tends to list the directories as well I need to scan the folders and print the files in the folder and sub folders in sorted manner.

I tried using find but coudn't find a suitable solution.

share|improve this question
Do you want to list the files in each subdirectory separately or do you want to find all files in all subdirs and list them by size irrespective of which subdir they are in? Also, what do you mean by "directory" and "folder"? You seem to be using them to describe different things. – terdon Aug 24 '13 at 16:05
Are you saying that you just want to list the files in a given directory as well as the files in its sub-directories without showing just the sub-directories? Please try and clean up you question, it's not very clear. – slm Aug 24 '13 at 16:25
up vote 30 down vote accepted

You can also do this with just du. Just to be on the safe side I'm using this version of du:

$ du --version
du (GNU coreutils) 8.5

The approach:

$ du -ah ..DIR.. | grep -v "/$" | sort -rh

Breakdown of approach

The command du -ah DIR will produce a list of all the files and directories in a given directory DIR. The -h will produce human readable sizes which I prefer. If you don't want them then drop that switch. I'm using the head -6 just to limit the amount of output!

$ du -ah ~/Downloads/ | head -6
4.4M    /home/saml/Downloads/kodak_W820_wireless_frame/W820_W1020_WirelessFrames_exUG_GLB_en.pdf
624K    /home/saml/Downloads/kodak_W820_wireless_frame/easyshare_w820.pdf
4.9M    /home/saml/Downloads/kodak_W820_wireless_frame/W820_W1020WirelessFrameExUG_GLB_en.pdf
9.8M    /home/saml/Downloads/kodak_W820_wireless_frame
8.0K    /home/saml/Downloads/bugs.xls
604K    /home/saml/Downloads/netgear_gs724t/GS7xxT_HIG_5Jan10.pdf

Easy enough to sort it smallest to biggest:

$ du -ah ~/Downloads/ | sort -h | head -6
0   /home/saml/Downloads/apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios/plugins/check_ldaps
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/0/index/write.lock
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/0/translog/translog-1365292480753
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/1/index/write.lock
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/1/translog/translog-1365292480946
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/2/index/write.lock

Reverse it, biggest to smallest:

$ du -ah ~/Downloads/ | sort -rh | head -6
10G /home/saml/Downloads/
3.8G    /home/saml/Downloads/audible/audio_books
3.8G    /home/saml/Downloads/audible
2.3G    /home/saml/Downloads/apps_archive
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
1.5G    /home/saml/Downloads/digital_blasphemy

Don't show me the directory, just the files:

$ du -ah ~/Downloads/ | grep -v "/$" | sort -rh | head -6 
3.8G    /home/saml/Downloads/audible/audio_books
3.8G    /home/saml/Downloads/audible
2.3G    /home/saml/Downloads/apps_archive
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
1.5G    /home/saml/Downloads/digital_blasphemy
835M    /home/saml/Downloads/apps_archive/cad_cam_cae/salome/Salome-V6_5_0-LGPL-x86_64.run

If you just want the list of smallest to biggest, but the top 6 offending files you can reverse the sort switch, drop (-r), and use tail -6 instead of the head -6.

$ du -ah ~/Downloads/ | grep -v "/$" | sort -h | tail -6
835M    /home/saml/Downloads/apps_archive/cad_cam_cae/salome/Salome-V6_5_0-LGPL-x86_64.run
1.5G    /home/saml/Downloads/digital_blasphemy
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
2.3G    /home/saml/Downloads/apps_archive
3.8G    /home/saml/Downloads/audible
3.8G    /home/saml/Downloads/audible/audio_books
share|improve this answer
The grep -v "/$" part doesn't seem to be doing what you expected, as the directories don't have a slash appended. Does anyone know how to exclude directories from results? – Janek Warchoł Feb 16 '15 at 10:14
@JanekWarchol - what version of coreutils are you using? – slm Feb 16 '15 at 12:53
I'm on 8.13. But anyway, the output in your answer doesn't have trailing /s either - for example /home/saml/Downloads/audible seems to be a directory, but it doesn't have a slash. Only /home/saml/Downloads/ has a slash, but that's probably because you wrote it with a slash when specifying the argument for initial du. – Janek Warchoł Feb 16 '15 at 13:55
@JanekWarchol - Look at the 5th text box. The grep is just to filter the ~/Downloads/ bit out. As you've stated, it's just to filter out the argument of ~/Downloads when du processes it. I changed the word directories to directory since I think that's ultimately what was causing the confusion. Thanks for the feedback! – slm Feb 16 '15 at 14:46
@JanekWarchol - incidentally to omit the directories you'll have to change tactics and use find to generate a list of files only and then have du tally them up. – slm Feb 16 '15 at 14:50

If you want to find all files in the current directory and its sub directories and list them according to their size (without considering their path), and assuming none of the file names contain newline characters, with GNU find, you can do this:

find . -type f -printf "%s\t%p\n" | sort -n

From man find on a GNU system:

   -printf format
          True; print format  on  the  standard  output,
          interpreting  `\'  escapes and `%' directives.
          Field widths and precisions can  be  specified
          as  with the `printf' C function.  Please note
          that many of the  fields  are  printed  as  %s
          rather  than  %d, and this may mean that flags
          don't work as you  might  expect.   This  also
          means  that  the `-' flag does work (it forces
          fields to be  left-aligned).   Unlike  -print,
          -printf  does  not add a newline at the end of
          the string.  The escapes and directives are:

          %p     File's name.
          %s     File's size in bytes.

From man sort:

   -n, --numeric-sort
          compare according to string numerical value
share|improve this answer

Try the following command:

ls -1Rhs | sed -e "s/^ *//" | grep "^[0-9]" | sort -hr | head -n20

It'll list top-20 biggest files in the current directory recursively.

Note: The option -h for sort is not available on OSX/BSD, so you've to install sort from coreutils (e.g. via brew) and apply the local bin path to PATH, e.g.

export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" # Add a "gnubin" for coreutils.

Alternatively use:

ls -1Rs | sed -e "s/^ *//" | grep "^[0-9]" | sort -nr | head -n20

For the biggest directories use du, e.g.:

du -ah . | sort -rh | head -20


du -a . | sort -rn | head -20
share|improve this answer

With zsh, you'd find the biggest file with:

ls -ld -- **/*(DOL[1])
share|improve this answer

The equivalent in BSD or OSX is

$ du -ah simpl | sort -dr | head -6
share|improve this answer

This will find all files recursively, and sort them by size. It prints out all file sizes in kb, and rounds down so you may see 0 KB files, but it was close enough for my uses, and works on OSX.

find . -type f -print0 | xargs -0 ls -la | awk '{print int($5/1000) " KB\t" $9}' | sort -n -r -k1

share|improve this answer
Thanks, this is the best solution for OS X! – mamiu Jun 11 '15 at 21:58
worked on Ubuntu 14.04 too! – David Lam yesterday

Your Answer


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.