How do I find the largest 10 files in a given directory?
Asked Answered
R

5

7

How do I find the largest 10 files in a given directory, with Perl or Bash?

EDIT:

  • I need this to be recursive.
  • I only want to see large files, no large directories.
  • I need this to work on Mac OS X 10.6 ('s version of find).
Reluctant answered 1/1, 2012 at 23:26 Comment(0)
F
6

This prints the 10 largest files recursively from current directory.

find . -type f -printf "%s %p\n" | sort -nr | awk '{print $2}' | head -10
Fabri answered 2/1, 2012 at 0:6 Comment(5)
How to also print out their sizes to verify the result are correct?Reluctant
$ find . -type f -printf "%s %p\n" | sort -nr | head -10 works.Reluctant
Actually this doesn't work on Mac OS X. It doesn't have a printf option.Reluctant
@user001 without using -printf option, you can try this: find . -type f -ls | awk '{print $7" "$11}' | sort -nr | head -10Fabri
find . -type f -ls | awk '{print $7" "$11}' | sort -nr | head -10 prints nothing.Reluctant
T
5
$ alias ducks
alias ducks='du -cs * |sort -rn |head -11'
Tropic answered 1/1, 2012 at 23:27 Comment(1)
Doesn't this output include subdirectories?Naturalistic
A
5

This is a way to do it in perl. (Note: Non-recursive version, according to earlier version of the question)

perl -wE 'say for ((sort { -s $b <=> -s $a } </given/dir/*>)[0..9]);'

However, I'm sure there are better tools for the job.

ETA: Recursive version, using File::Find:

perl -MFile::Find -wE '
    sub wanted { -f && push @files, $File::Find::name }; 
    find(\&wanted, "/given/dir"); 
    @files = sort { -s $b <=> -s $a } @files; 
    say for @files[0..9];'

To check file sizes, use e.g. printf("%-10s : %s\n", -s, $_) for @files[0..9]; instead.

Alvy answered 1/1, 2012 at 23:44 Comment(2)
Tanks for giving the Perl solution. I am wondering if this has significantly different memory footprint from the solution using find?Reluctant
@user001 I don't know how find works internally, so I cannot say. It may also vary depending on your file system and number of files. You'd need to try it out and see.Alvy
A
0

How about this -

find . -type f -exec ls -l {} + | awk '{print $5,$NF}' | sort -nr | head -n 10

Test:

[jaypal:~/Temp] find . -type f -exec ls -l {} + | awk '{print $5,$NF}' | sort -nr | head -n 10
8887 ./backup/GTP/GTP_Parser.sh
8879 ./backup/Backup/GTP_Parser.sh
6791 ./backup/Delete_HIST_US.sh
6785 ./backup/Delete_NORM_US.sh
6725 ./backup/Delete_HIST_NET.sh
6711 ./backup/Delete_NORM_NET.sh
5339 ./backup/GTP/gtpparser.sh
5055 ./backup/GTP/gtpparser3.sh
4830 ./backup/GTP/gtpparser2.sh
3955 ./backup/GTP/temp1.file
Arteriole answered 3/1, 2012 at 1:2 Comment(5)
This is not a solution to what I asked. It outputs a bunch of directories.Reluctant
@user001 I have added sample output from the one-liner tested on Mac OSX LionArteriole
Thanks, it works correctly. I ran it in a wrong directory where there were no file.Reluctant
@user001 :) No worries. I was a little skeptical of the accepted answer since it used find's printf option which isn't available in mac.Arteriole
Don't use {} in shell part to avoid shell injectionShirr
W
0

With recent find (2023) and bash:

I use GNU findutils 4.9.0

shopt -s nullglob

print0 () { 
    [ "$#" -eq 0 ] || printf '%s\0' "$@"
}
readarray -td '' files < <(
    print0 * |
    find -files0-from - -type f -printf '%b\t%p\0' |
    sort -rzn |
    cut -zf2 -
) 
printf '%s\n' "${files[@]:0:10}"
  • this allow all types of files (newlines, spaces, special characters...)
  • ${files[@]:0:10} is taking files array element from key 0 to 10
Wavawave answered 1/5, 2023 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.