119

We're just starting a UNIX class and are learning a variety of Bash commands. Our assignment involves performing various commands on a directory that has a number of folders under it as well.

I know how to list and count all the regular files from the root folder using:

find . -type l | wc -l

But I'd like to know where to go from there in order to find the largest file in the whole directory. I've seen somethings regarding a du command, but we haven't learned that, so in the repertoire of things we've learned I assume we need to somehow connect it to the ls -t command.

And pardon me if my 'lingo' isn't correct, I'm still getting used to it!

jww
  • 97,681
  • 90
  • 411
  • 885
Rekson
  • 1,293
  • 3
  • 12
  • 13
  • 2
    If you know of a command, but aren't sure how to use it then try typing in `man` followed by the command you are interested in. Up will pop a nice manual entry for that command (press `q` to get back to command line). – Dunes Sep 21 '12 at 00:07
  • related: https://unix.stackexchange.com/questions/140367/finding-all-large-files-in-the-root-filesystem – Ciro Santilli OurBigBook.com May 21 '19 at 13:35

17 Answers17

138

Quote from this link-

If you want to find and print the top 10 largest files names (not directories) in a particular directory and its sub directories

$ find . -type f -printf '%s %p\n'|sort -nr|head

To restrict the search to the present directory use "-maxdepth 1" with find.

$ find . -maxdepth 1 -printf '%s %p\n'|sort -nr|head

And to print the top 10 largest "files and directories":

$ du -a . | sort -nr | head

** Use "head -n X" instead of the only "head" above to print the top X largest files (in all the above examples)

user2297550
  • 3,142
  • 3
  • 28
  • 39
tamsler
  • 1,275
  • 1
  • 18
  • 26
  • 1
    Why does "du -a . | sort -nr | head" return double the number of KB than the actual file size? – xxjjnn Oct 30 '13 at 10:22
  • 7
    Ah, you need to add the 'k' option or it shows multiples of 512 bytes rather than of 1024. du -ak – xxjjnn Oct 30 '13 at 14:23
  • 2
    for the first one, how do you get the size in a human readable format? – Bluz Oct 18 '16 at 15:54
  • @Bluz I'd try replacing `'%s %p\n'` with `'%p\n'` and adding `|xargs ls -lh` to the end – Dessa Simpson Jan 01 '17 at 16:02
  • 6
    The first solution didn't work on OS X for me, so i ended up using a quick hack to filter out the directories from the third solution: `du -am . | sort -nr | grep '\..*\.' | head`. The `m` is to display file size in megabytes and used `grep` to show lines with at least two dots, the first is in the `./` in the path, the second is in the file extension, e.g. `.mov`. – psmith Apr 15 '17 at 15:48
  • @psmith Your hack is really a "dirty" one since Unix-like operating systems are essentially extensionless so this solution won't work for **files without extensions**. And as said it's better to use `du -ah` for displaying human-readable file sizes. – murla Jun 20 '18 at 21:50
  • @DuncanXSimpson you can't replace `%s %p\n` with `%p\n` because `%s` is size here and used for sorting and finding the largest file. – murla Jun 20 '18 at 22:17
  • To use this on MacOS, if you have Homebrew installed you can run `brew install findutils` and then replace `find` with `gfind` in the above commands. – jbg Feb 08 '19 at 16:55
  • why not remove the source reference and quote since the `find` needs a `-type f` that the source does not have – user2297550 Nov 13 '21 at 09:02
  • You can use `numfmt` to generate a human readable output: `find . -type f -printf '%s %p\n'| numfmt --to=iec | sort -hr | head` – Christophe Messaouik Feb 26 '23 at 15:19
74

To find the top 25 files in the current directory and its subdirectories:

find . -type f -exec ls -al {} \; | sort -nr -k5 | head -n 25

This will output the top 25 files by sorting based on the size of the files via the "sort -nr -k5" piped command.

Same but with human-readable file sizes:

find . -type f -exec ls -alh {} \; | sort -hr -k5 | head -n 25

murla
  • 95
  • 2
  • 10
xpros
  • 2,166
  • 18
  • 15
10
find . -type f | xargs ls -lS | head -n 1

outputs

-rw-r--r--  1 nneonneo  staff  9274991 Apr 11 02:29 ./devel/misc/test.out

If you just want the filename:

find . -type f | xargs ls -1S | head -n 1

This avoids using awk and allows you to use whatever flags you want in ls.

Caveat. Because xargs tries to avoid building overlong command lines, this might fail if you run it on a directory with a lot of files because ls ends up executing more than once. It's not an insurmountable problem (you can collect the head -n 1 output from each ls invocation, and run ls -S again, looping until you have a single file), but it does mar this approach somewhat.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • 1
    i'm sorry `xargs`, i have neglected you +1 – Steve Sep 21 '12 at 03:52
  • 3
    to handle filenames with spaces, use `find . -type f -print0 | xargs -0 ls -lS | head -n 1` – rymo Nov 04 '13 at 03:18
  • This finds the biggest files in only the first batch `xargs` has executed. To fix it add sorting: `find . -type f -print0 | xargs -0 ls -lS | sort -rk 5 | head -n 10`. Worked on OSX for me. – psmith Apr 15 '17 at 16:08
10

There is no simple command available to find out the largest files/directories on a Linux/UNIX/BSD filesystem. However, combination of following three commands (using pipes) you can easily find out list of largest files:

# du -a /var | sort -n -r | head -n 10

If you want more human readable output try:

$ cd /path/to/some/var
$ du -hsx * | sort -rh | head -10

Where,

  • Var is the directory you wan to search
  • du command -h option : display sizes in human readable format (e.g., 1K, 234M, 2G).
  • du command -s option : show only a total for each argument (summary).
  • du command -x option : skip directories on different file systems.
  • sort command -r option : reverse the result of comparisons.
  • sort command -h option : compare human readable numbers. This is GNU sort specific option only.
  • head command -10 OR -n 10 option : show the first 10 lines.
Kalpana
  • 491
  • 1
  • 7
  • 21
  • I like the 2nd command better but on osx, no -h option for sort version installed. Should be for mac: du -hsx * | sort -rn | head -10 – Yann VR Nov 06 '16 at 20:24
  • 1
    Loving that second command! Best of all the ones I've tried - I'll be saving it for later. – CodeMouse92 May 11 '17 at 18:31
9

This lists files recursively if they're normal files, sorts by the 7th field (which is size in my find output; check yours), and shows just the first file.

find . -type f -ls | sort +7 | head -1

The first option to find is the start path for the recursive search. A -type of f searches for normal files. Note that if you try to parse this as a filename, you may fail if the filename contains spaces, newlines or other special characters. The options to sort also vary by operating system. I'm using FreeBSD.

A "better" but more complex and heavier solution would be to have find traverse the directories, but perhaps use stat to get the details about the file, then perhaps use awk to find the largest size. Note that the output of stat also depends on your operating system.

ghoti
  • 45,319
  • 8
  • 65
  • 104
  • 1
    What is the `+7` arg meant to be doing? On my machine sort just complains that it can't find a file called `+7`. – Dunes Sep 20 '12 at 23:59
  • @Dunes - As I said, check the man page for `sort` on your system. [I'm using OS X 10.4 at the moment, where usage derives from FreeBSD's sort](http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/10.4-intel/man1/sort.1.html): `sort [-cmus] [-t separator] [-o output-file] [-T tempdir] [-bdfiMnr] [+POS1 [-POS2]] [-k POS1[,POS2]] [file...]` ... Note the `+POS [-POS2]`. This works in current versions of FreeBSD too. – ghoti Sep 25 '12 at 23:23
  • 2
    Seems you have a different sort program to me. This is the man page for my sort program -- http://linux.die.net/man/1/sort For this to work on my machine you would need to explicitly use the `-k` arg eg. `sort -k 7`. edit: by OSX 10.5 the man page for sort seems to have changed to the version I have. – Dunes Sep 26 '12 at 10:53
  • 1
    @Dunes - It's all GNU sort, but different versions. The `[+POS1] [-POS2]` notation is just an older one. As far as I can tell, this notation is still supported by modern GNU sort, though now that I look, it seems to have been dropped from the sort man page after around version 5.1. You can see it in the man page for [sort for FreeBSD 4.11](http://www.freebsd.org/cgi/man.cgi?query=sort&apropos=0&sektion=0&manpath=FreeBSD+4.11-RELEASE). I guess I haven't read sort's man page since before FreeBSD 5.0 was released! – ghoti Sep 26 '12 at 11:41
  • Also, note that `+POS1` counts sort parameters from zero, whereas `-k POS1` counts from one. – ghoti Sep 26 '12 at 11:42
  • @Nakilon, thanks for checking. OSX is diverging then, as FreeBSD 10.0 still supports the old notation, though the man page describes it as "obsolete". – ghoti Nov 16 '13 at 02:15
  • This worked for me, though in CentOS I had to modify the code: ```find . -type f -ls | sort -nk 7 | head -1``` – Parapluie Mar 01 '22 at 18:18
6

This will find the largest file or folder in your present working directory:

ls -S /path/to/folder | head -1

To find the largest file in all sub-directories:

find /path/to/folder -type f -exec ls -s {} \; | sort -nr | awk 'NR==1 { $1=""; sub(/^ /, ""); print }'
Steve
  • 51,466
  • 13
  • 89
  • 103
  • I think the default behaviour of ls is to list files in columns (ie. several entries per line), so the first doesn't exactly find just the largest file. With regards to your second command it only found the largest file in the given directory and not its subdirectories. – Dunes Sep 20 '12 at 23:57
  • @Dunes: You are correct, the first command _could_ find directories, but not because of default behavior of `ls`. In my testing, the `-S` flag will list one file per line. I have corrected the second command. Hopefully now it's full-proof. Thank-you. – Steve Sep 21 '12 at 00:58
4

On Solaris I use:

find . -type f -ls|sort -nr -k7|awk 'NR==1{print $7,$11}' #formatted

or

find . -type f -ls | sort -nrk7 | head -1 #unformatted

because anything else posted here didn't work. This will find the largest file in $PWD and subdirectories.

rindeal
  • 993
  • 11
  • 16
2

Try following command :

find /your/path -printf "%k %p\n" | sort -g -k 1,1 | awk '{if($1 > 500000) print $1/1024 "MB" " " $2 }' |tail -n 1 

This will print the largest file name and size and more than 500M. You can move the if($1 > 500000),and it will print the largest file in the directory.

Jad Chahine
  • 6,849
  • 8
  • 37
  • 59
zjhui
  • 779
  • 1
  • 8
  • 21
2

Try the following one-liner (display top-20 biggest files):

ls -1Rs | sed -e "s/^ *//" | grep "^[0-9]" | sort -nr | head -n20

or (human readable sizes):

ls -1Rhs | sed -e "s/^ *//" | grep "^[0-9]" | sort -hr | head -n20

Works fine under Linux/BSD/OSX in comparison to other answers, as find's -printf option doesn't exist on OSX/BSD and stat has different parameters depending on OS. However the second command to work on OSX/BSD properly (as sort doesn't have -h), install sort from coreutils or remove -h from ls and use sort -nr instead.

So these aliases are useful to have in your rc files:

alias big='du -ah . | sort -rh | head -20'
alias big-files='ls -1Rhs | sed -e "s/^ *//" | grep "^[0-9]" | sort -hr | head -n20'
kenorb
  • 155,785
  • 88
  • 678
  • 743
1

du -aS /PATH/TO/folder | sort -rn | head -2 | tail -1

or

du -aS /PATH/TO/folder | sort -rn | awk 'NR==2'

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
1

To list the larger file in a folder

ls -sh /pathFolder | sort -rh | head -n 1

The output of ls -sh is a sized s and human h understandable view of the file size number.

You could use ls -shS /pathFolder | head -n 1. The bigger S from ls already order the list from the larger files to the smaller ones but the first result its the sum of all files in that folder. So if you want just to list the bigger file, one file, you need to head -n 2 and check at the "second line result" or use the first example with ls sort head.

1

This command works for me,

find /path/to/dir -type f -exec du -h '{}' + | sort -hr | head -10

Lists Top 10 files ordered by size in human-readable mode.

AATHITH RAJENDRAN
  • 4,689
  • 8
  • 34
  • 58
0

This script simplifies finding largest files for further action. I keep it in my ~/bin directory, and put ~/bin in my $PATH.

#!/usr/bin/env bash
# scriptname: above
# author: Jonathan D. Lettvin, 201401220235

# This finds files of size >= $1 (format ${count}[K|M|G|T], default 10G)
# using a reliable version-independent bash hash to relax find's -size syntax.
# Specifying size using 'T' for Terabytes is supported.
# Output size has units (K|M|G|T) in the left hand output column.

# Example:
#   ubuntu12.04$ above 1T
#   128T /proc/core

# http://stackoverflow.com/questions/1494178/how-to-define-hash-tables-in-bash
# Inspiration for hasch: thanks Adam Katz, Oct 18 2012 00:39
function hasch() { local hasch=`echo "$1" | cksum`; echo "${hasch//[!0-9]}"; }
function usage() { echo "Usage: $0 [{count}{k|K|m|M|g|G|t|T}"; exit 1; }
function arg1() {
    # Translate single arg (if present) into format usable by find.
    count=10; units=G;  # Default find -size argument to 10G.
    size=${count}${units}
    if [ -n "$1" ]; then
        for P in TT tT GG gG MM mM Kk kk; do xlat[`hasch ${P:0:1}`]="${P:1:1}"; done
        units=${xlat[`hasch ${1:(-1)}`]}; count=${1:0:(-1)}
        test -n "$units" || usage
        test -x $(echo "$count" | sed s/[0-9]//g) || usage
        if [ "$units" == "T" ]; then units="G"; let count=$count*1024; fi
        size=${count}${units}
    fi
}
function main() {
    sudo \
        find / -type f -size +$size -exec ls -lh {} \; 2>/dev/null | \
        awk '{ N=$5; fn=$9; for(i=10;i<=NF;i++){fn=fn" "$i};print N " " fn }'
}

arg1 $1
main $size
jlettvin
  • 1,113
  • 7
  • 13
0

That is quite simpler way to do it:

ls -l | tr -s " " " " | cut -d " " -f 5,9 | sort -n -r | head -n 1***

And you'll get this: 8445 examples.desktop

Daniel Serodio
  • 4,229
  • 5
  • 37
  • 33
Andrii Kovalchuk
  • 4,351
  • 2
  • 36
  • 31
0

Linux Solution: For example, you want to see all files/folder list of your home (/) directory according to file/folder size (Descending order).

sudo du -xm / | sort -rn | more

Monir
  • 1,402
  • 14
  • 16
0
ls -alR|awk '{ if ($5 > max) {max=$5;ff=$9}} END {print max "\t" ff;}'
Borislav Markov
  • 1,495
  • 11
  • 12
0

Kindly run below one liner with your required-path. as of now i am running for /var/log/ location

 (sudo  du -a /var/log/ |sort -nr|head -n20 |awk '{print $NF}'|while read l ;do du -csh $l|grep -vi total;done ) 2> /dev/null
linux.cnf
  • 519
  • 6
  • 7