Super User is a question and answer site for computer enthusiasts and power users. 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

I want to list the top 5 image files (png,jpg) in a given folder.What's the best approach? I'm using the following currently but it doesn't give the right output:

find . \( -iname \*.png -o -iname \*.jpg \)  -exec ls -lrhS {} \; | sort -n | head -5 | awk '{print $9, "=>",$5}'

When I don't pipe to head command, I see that the output isn't sorted correctly. How can I achieve this

share|improve this question
Since you run ls individually per file, its sorting function won't work. It will "sort" every file individually, so to speak. – Daniel Andersson Apr 6 '12 at 9:35

If by "top 5" you mean by size, then you need to tell sort which column to sort by; the default will go through all the columns in order, meaning it's going to sort initially by the number of links. Additionally, without some kind of extension the "human readable" size is not going to sort at all sanely except in GNU sort; portable sort -n does not know about suffixes like B, K, etc. Note also that you lose the sort information you asked ls for because it's being run on individual files under control of find. And then your sort sorts from lowest to highest, so even fixing that you get the five smallest images from head. (And is the || before awk a typo? You're saying to run awk only if the find pipeline fails.)

Combining all of this and optimizing by using xargs to batch things up and combining the head into the awk, what you want is to make sure you have GNU sort, then use

find . \( -iname \*.png -o -iname \*.jpg \) -print0 | xargs -0 ls -lh | sort -k5gr,5 | awk 'NR <= 5 {print $9, "=>", $5}'
share|improve this answer
the || before awk is indeed a typo. Also how do I find if I have the GNU sort? I'm on MAC OSX – smokinguns Apr 6 '12 at 5:25
sort --version will return useful information for GNU sort or an error for traditional Unix sort, or possibly information about some other implementation — but OS X uses the version of GNU sort that the version of FreeBSD it last synced with uses (I believe that's FreeBSD 8.0 for Lion; sort is GNU sort 5.93.) – geekosaur Apr 6 '12 at 5:54
geekosaur : The command didnt give me the correct output. What does "sort -k5gr,5" do exactly? – smokinguns Apr 6 '12 at 6:07
It means general numeric sort (which in GNU sort is supposed to support things like 1.1K) reversed, from column 5 to column 5 (that is, just the one column). (It is 1-based, unlike the usual 0-based computer thing.) That said, I just tried it here and it looks like while GNU sort claims to handle the size suffixes on numeric columns, it actually doesn't; you will have to give up on the -h option to ls, and maybe change the awk script to do it instead. – geekosaur Apr 6 '12 at 6:16
find . \( -iname "*.png" -o -iname "*.jpg" \) -printf "%k\t%p\n" | sort -rn | head -5
  1. Uses find according to your requirements in the current directory (I assume you mean "current directory AND subdirectories, otherwise add -maxdepth 1).
  2. Prints size (in 1K blocks), followed by tab, followed by filename.
  3. Sorts numerically reversed.
  4. Picks out the first five lines.

et voilà!

(Possible caveat is file names containing newlines, but in practice I have never seen these. Requires some simple modification to account for that as well)

share|improve this answer
I get an error : find: -printf: unknown option. Looks like I will have to install findutils – smokinguns Apr 6 '12 at 15:47
@smokinguns Exactly. Are you on OS X or a BSD variant? You need GNU find for that, for example through Homebrew. – slhck Apr 6 '12 at 15:59
up vote 1 down vote accepted

Thanks to all pointing me in the right direction. I think I got it to work using:

find . \( -iname \*.png -o -iname \*.jpg \) -print0 | xargs -0 ls -l | sort -k5 -r | head -5

I will process this output to get the output in desired format(i.e. with suffixes like B, K)

share|improve this answer

Do you mean "top" as in largest by size? The S in your ls command already sorts by size, but r reverses the order, sorting smallest to the top. Perhaps you want to try -exec ls -lhS {} \; | head -5 (omit the separate sort).

share|improve this answer
Sorting the output of ls (with l -S) is pointless, becaue ls executes on only a single file at a time; courtesy of {} \; – Peter.O Apr 6 '12 at 7:25
@Peter.O -- You're absolutely right, I missed that. I suppose one could omit the find completely using something like ls -lhS *.png *.PNG *.jpg *.JPG | head -5 | awk '{print $9, "=>",$5}'. Depends on what suits his needs. – Lars Rohrbach Apr 6 '12 at 15:04

Sort of very straightforward:

find . -ls | sort -nk7 | tail -5
share|improve this answer
This doesn't restrict to image files, and gives a lot of for the task unnecessary information. – Daniel Andersson Apr 6 '12 at 9:31
Asker knows how to list files in good format. I just illustrate how to get 10 top records based on numeric field in 7th position. I assume asker's creativity is enough to correct my deliberate omissions. – ZaB Apr 9 '12 at 13:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .