2

I want to do something like this

du -a | sort -rn | head

But I want to extract files only, ignoring directories.

To be clear, I want to traverse through all sub-directories but I don't want to find directory sizes. Just files sizes.

UPDATE

I also want to return the full path of the files

3 Answers 3

6

This should work:

find <path> -type f -exec du -a{} + | sort -rn | head

Taken from http://unix-linux.itags.org/q_unix-linux-programming_84920.html

5
  • Just a note this works on Debian but not on BSD Unix (as tested) Oct 12, 2012 at 7:43
  • @superspace: It might be useful to say exactly how it doesn't work. My guess is that changing + to \; might be all that you need to change. Oct 12, 2012 at 17:18
  • @DennisWilliamson True. + resulted in this error: find: -exec: no terminating ";" or "+". However, replacing + with \; resulted in other errors: du: illegal option -- . Oct 15, 2012 at 1:06
  • 1
    UPDATE: This works on BSD (note space between -a and {}): find . -type f -exec du -a {} \; | sort -rn | head Oct 15, 2012 at 1:12
  • changing from + to \; also makes the script run 10x slower :( Oct 15, 2012 at 1:13
2

One way to find the largest file in a directory:

find . -type f | xargs ls -1S | head -n 1
3
  • Does everything I've requested, but beaten to the pip by the other answer. Oct 12, 2012 at 2:34
  • @superspace: That's ok, our answers are a little different anyway. I didn't realize you wanted the filesize printed ahead of the directory name.
    – Steve
    Oct 12, 2012 at 2:43
  • The file size was a bonus. He pipped you by coming in first :) Otherwise I would have awarded the answer to you cause as I said you fulfilled the requirements of the question. Oct 12, 2012 at 2:48
1

I just want to add my solution although it's not as complete as the one by @Michael Plotke

ls -lR | egrep "^-" | awk '{ print $5, "\t", $8 }' | sort -rn | head

UPDATE 1

I've now had to use this script on BSD unix (which I did not originally intended to do) and found Michael's solution doesn't work.

By incorporating @steve's solution into mine, this solution is more usable on BSD systems:

find . -type f | xargs ls -lS | awk '{ print $5, "\t", $9 }' | head

UPDATE 2

Further refinement. Resolves issues with unusual filenames (eg. spaces)

find . -type f -print0 | xargs -0 ls -lS | awk '{ print $5, "\t", $9 }' | head

Note: I found this solution to be significantly faster on WSL (windows subsystem Linux) than the accepted solution.

In a directory with about 1000 files, this solution takes seconds whereas the accepted answer took tens of minutes.

2
  • This sub-obtimal solution works on Debian Oct 12, 2012 at 7:44
  • 1
    Instead of the pipe to head, awk can accomplish it too. Simply try piping into: awk 'NR<=10 { print $5 "\t" $9 }'
    – Steve
    Oct 12, 2012 at 10:43

You must log in to answer this question.

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