Linux find sort by size

How to list the size of each file and directory and sort by descending size in Bash?

I found that there is no easy to get way the size of a directory in Bash? I want that when I type ls — , it can list of all the sum of the file size of directory recursively and files at the same time and sort by size order. Is that possible?

What exactly do you mean by the «size» of a directory? The number of files under it (recursively or not)? The sum of the sizes of the files under it (recursively or not)? The disk size of the directory itself? (A directory is implemented as a special file containing file names and other information.)

@KeithThompson @KitHo du command estimates file space usage so you cannot use it if you want to get the exact size.

@ztank1013: Depending on what you mean by «the exact size», du (at least the GNU coreutils version) probably has an option to provide the information.

12 Answers 12

Simply navigate to directory and run following command:

OR add -h for human readable sizes and -r to print bigger directories/files first.

du -a -h --max-depth=1 | sort -hr 

du -h requires sort -h too, to ensure that, say 981M sorts before 1.3G ; with sort -n only the numbers would be taken into account and they’d be the wrong way round.

This doesn’t list the size of the individual files within the current directory, only the size of its subdirectories and the total size of the current directory. How would you include individual files in the output as well (to answer OP’s question)?

@ErikTrautman to list the files also you need to add -a and use —all instead of —max-depth=1 like so du -a -h —all | sort -h

Apparently —max-depth option is not in Mac OS X’s version of the du command. You can use the following instead.

Unfortunately this does not show the files, but only the folder sizes. -a does not work with -d either.

To show files and folders, I combined 2 commands: l -hp | grep -v / && du -h -d 1 , which shows the normal file size from ls for files, but uses du for directories.

(this willnot show hidden (.dotfiles) files)

Use du -sm for Mb units etc. I always use

because the total line ( -c ) will end up at the bottom for obvious reasons 🙂

PS:

  • See comments for handling dotfiles
  • I frequently use e.g. ‘du -smc /home// | sort -n |tail’ to get a feel of where exactly the large bits are sitting

du —max-depth=1|sort -n or find . -mindepth 1 -maxdepth 1|xargs du -s|sort -n for including dotfiles too.

@arnaud576875 find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 du -s | sort -n if some of the found paths could contain spaces.

This is a great variant to get a human readable view of the biggest: sudo du -smch * | sort -h | tail

Command

Output

3,5M asdf.6000.gz 3,4M asdf.4000.gz 3,2M asdf.2000.gz 2,5M xyz.PT.gz 136K xyz.6000.gz 116K xyz.6000p.gz 88K test.4000.gz 76K test.4000p.gz 44K test.2000.gz 8,0K desc.common.tcl 8,0K wer.2000p.gz 8,0K wer.2000.gz 4,0K ttree.3 

Explanation

  • du displays «disk usage»
  • h is for «human readable» (both, in sort and in du)
  • max-depth=0 means du will not show sizes of subfolders (remove that if you want to show all sizes of every file in every sub-, subsub-, . folder)
  • r is for «reverse» (biggest file first)
Читайте также:  Linux mint связка ключей убрать

ncdu

When I came to this question, I wanted to clean up my file system. The command line tool ncdu is way better suited to this task.

Just type ncdu [path] in the command line. After a few seconds for analyzing the path, you will see something like this:

$ ncdu 1.11 ~ Use the arrow keys to navigate, press ? for help --- / --------------------------------------------------------- . 96,1 GiB [##########] /home . 17,7 GiB [# ] /usr . 4,5 GiB [ ] /var 1,1 GiB [ ] /lib 732,1 MiB [ ] /opt . 275,6 MiB [ ] /boot 198,0 MiB [ ] /storage . 153,5 MiB [ ] /run . 16,6 MiB [ ] /etc 13,5 MiB [ ] /bin 11,3 MiB [ ] /sbin . 8,8 MiB [ ] /tmp . 2,2 MiB [ ] /dev ! 16,0 KiB [ ] /lost+found 8,0 KiB [ ] /media 8,0 KiB [ ] /snap 4,0 KiB [ ] /lib64 e 4,0 KiB [ ] /srv ! 4,0 KiB [ ] /root e 4,0 KiB [ ] /mnt e 4,0 KiB [ ] /cdrom . 0,0 B [ ] /proc . 0,0 B [ ] /sys @ 0,0 B [ ] initrd.img.old @ 0,0 B [ ] initrd.img @ 0,0 B [ ] vmlinuz.old @ 0,0 B [ ] vmlinuz 

Delete the currently highlighted element with d , exit with CTRL + c

ls -S sorts by size. Then, to show the size too, ls -lS gives a long ( -l ), sorted by size ( -S ) display. I usually add -h too, to make things easier to read, so, ls -lhS .

Ah, sorry, that was not clear from your post. You want du , seems someone has posted it. @sehe: Depends on your definition of real — it is showing the amount of space the directory is using to store itself. (It’s just not also adding in the size of the subentries.) It’s not a random number, and it’s not always 4KiB.

find . -mindepth 1 -maxdepth 1 -type d | parallel du -s | sort -n 

I think I might have figured out what you want to do. This will give a sorted list of all the files and all the directories, sorted by file size and size of the content in the directories.

(find . -depth 1 -type f -exec ls -s <> \;; find . -depth 1 -type d -exec du -s <> \;) | sort -n 

[enhanced version]
This is going to be much faster and precise than the initial version below and will output the sum of all the file size of current directory:

echo `find . -type f -exec stat -c %s <> \; | tr '\n' '+' | sed 's/+$//g'` | bc 

the stat -c %s command on a file will return its size in bytes. The tr command here is used to overcome xargs command limitations (apparently piping to xargs is splitting results on more lines, breaking the logic of my command). Hence tr is taking care of replacing line feed with + (plus) sign. sed has the only goal to remove the last + sign from the resulting string to avoid complains from the final bc (basic calculator) command that, as usual, does the math.

Performances: I tested it on several directories and over ~150.000 files top (the current number of files of my fedora 15 box) having what I believe it is an amazing result:

# time echo `find / -type f -exec stat -c %s <> \; | tr '\n' '+' | sed 's/+$//g'` | bc 12671767700 real 2m19.164s user 0m2.039s sys 0m14.850s 

Just in case you want to make a comparison with the du -sb / command, it will output an estimated disk usage in bytes ( -b option)

Читайте также:  Touch screen linux debian

As I was expecting it is a little larger than my command calculation because the du utility returns allocated space of each file and not the actual consumed space.

[initial version]
You cannot use du command if you need to know the exact sum size of your folder because (as per man page citation) du estimates file space usage. Hence it will lead you to a wrong result, an approximation (maybe close to the sum size but most likely greater than the actual size you are looking for).

I think there might be different ways to answer your question but this is mine:

ls -l $(find . -type f | xargs) | cut -d" " -f5 | xargs | sed 's/\ /+/g'| bc 

It finds all files under . directory (change . with whatever directory you like), also hidden files are included and (using xargs ) outputs their names in a single line, then produces a detailed list using ls -l . This (sometimes) huge output is piped towards cut command and only the fifth field ( -f5 ), which is the file size in bytes is taken and again piped against xargs which produces again a single line of sizes separated by blanks. Now take place a sed magic which replaces each blank space with a plus ( + ) sign and finally bc (basic calculator) does the math.

It might need additional tuning and you may have ls command complaining about arguments list too long.

Источник

Find and sort by file size

but the ls -lS gives the files that are less than 2 KB also. How can I display the names and sizes of the files that are larger than 2 KB, sorted by size?

3 Answers 3

 find . -size +2k -printf "%p \t%k kb\n" | sort -k2n 

Note that strictly speaking, that sorts by disk usage, not by size, though that’s likely what the OP wants anyway.

The ls command will list the current directory, not read something from stdin.

find . -size +2k -name *.log -printf "%s %p \t%k kb\n" | sort -n | sed -e '/^7* //' 
zmodload zsh/stat printf '%s\n' **/*.log(DLK+2oLe'[ stat -A blk +block -- $REPLY && REPLY+=" $((blk / 2)) KiB"]') 

That reports the disk usage of the log files whose size is greater that 2048, ordered by size.

You must log in to answer this question.

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.13.43531

Linux is a registered trademark of Linus Torvalds. UNIX is a registered trademark of The Open Group.
This site is not affiliated with Linus Torvalds or The Open Group in any way.

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

How to sort human readable size

I’m basically looking for files then sorting by the size. The script works if I don’t sort the size by human readable. But I want the size to be human readable. How can I sort sizes that are human readable? For example:

1.txt 1 test.txt 3 bash.sh* 573 DocGeneration.txt 1131 andres_stuff.txt 1465 Branches.xlsx 15087 foo 23735 bar 60566 2016_stuff.pdf 996850 

Now, I want the size to be human readable, so I added an -h parameter to ls, and now some files are out of order:

1.txt 1 DocGeneration.txt 1.2K andres_stuff.txt 1.5K test.txt 3 Branches.xlsx 15K foo 24K bar 60K bash.sh* 573 2016_stuff.pdf 974K 

@Jesse_b my error, I just assumed that the data in the question (marked as this is what I got) was the sorted input.I was wrong.

Читайте также:  Какие названия обозначают операционные системы linux ms dos microsoft access coreldraw

5 Answers 5

-h, —human-numeric-sort compare human readable numbers (e.g., 2K 1G)

It is part of gnu sort, BSD sort, and others.

@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output of ls , and instead use file globbing directly. Globbing alone won’t work here. That said, I would probably prefer du for this.

@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.

@Bloodgain : files=(); for f in *; do [[ -L «$f» ]] && files+=(«$f»); done; echo $ (I might have the is a symlink test switch wrong). If you don’t care about symlinks, files=(*); echo $ , which becomes portable if you use set and not arrays.

ls has this functionality built in, use the -S option and sort in reverse order: ls -lShr

 -r, --reverse reverse order while sorting -S sort by file size, largest first 

-h is not a standard ls option, but must be usable if OP already has it. The rest are standard, and it’s certainly the answer I would have written.

This is the best answer, but it should include the info in @Toby’s comment: -S might not be available for your ls . FWIW, -S is supported even with Emacs’s library ls-lisp.el , which is used when the OS has no ls . It works in Emacs on MS Windows, for example.

@Drew: Toby’s comment says that -h may not be universally available, but OP is already using it anyway. -S really should be universally available, because it’s in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.

Since no specific shell was mentioned, here’s how to do the whole thing in the zsh shell:

The ** glob pattern matches like * but across / in pathnames, i.e. like a recursive search would do.

The ls command would enable human readable sizes with -h , and long list output format with -l . The -f option disables sorting, so ls would just list the files in the order they are given.

This order is arranged by the **/*(.Lk-1024oL) filename globbing pattern so that the smaller files are listed first. The **/* bit matches every file and directory in this directory and below, but the (. ) modifies the glob’s behaviour (it’s a «glob qualifier»).

It’s the oL at the end that orders ( o ) the names by file size ( L , «length»).

The . at the start makes the glob only match regular files (no directories).

The Lk-1024 bit selects files whose size is less than 1024 KB («length in KB less than 1024»).

If zsh is not your primary interactive shell, then you could use

Use setopt GLOB_DOTS (or zsh -o GLOB_DOTS -c . ) to also match hidden names. . or just add D to the glob qualifier string.

Expanding on the above, assuming that you’d want a 2-column output with pathnames and human readable sizes, and also assuming that you have numfmt from GNU coreutils,

zmodload -F zsh/stat b:zstat for pathname in **/*(.Lk-1024oL); do printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)" done 

Источник

Оцените статью
Adblock
detector