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

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) – denormalizer Oct 12 '12 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. – Dennis Williamson Oct 12 '12 at 17:18
  • @DennisWilliamson True. + resulted in this error: find: -exec: no terminating ";" or "+". However, replacing + with \; resulted in other errors: du: illegal option -- . – denormalizer Oct 15 '12 at 1:06
  • UPDATE: This works on BSD (note space between -a and {}): find . -type f -exec du -a {} \; | sort -rn | head – denormalizer Oct 15 '12 at 1:12
  • changing from + to \; also makes the script run 10x slower :( – denormalizer Oct 15 '12 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. – denormalizer Oct 12 '12 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 '12 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. – denormalizer Oct 12 '12 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 – denormalizer Oct 12 '12 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 '12 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.