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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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