Calculate size of files in shell

LinuxShell

Linux Problem Overview


I'm trying to calculate the total size in bytes of all files (in a directory tree) matching a filename pattern just using the shell. This is what I have so far:

> find -name *.undo -exec stat -c%s {} ; | awk '{total += $1} END {print total}'

Is there an easier way to do this? I feel like there should be a simple du or find switch that does this for me but I can't find one.

To be clear I want to total files matching a pattern anywhere under a directory tree which means

> du -bs *.undo

won't work because it only matches the files in the current directory.

Linux Solutions


Solution 1 - Linux

Try:

find . -name "*.undo" -ls | awk '{total += $7} END {print total}'

On my system the size of the file is the seventh field in the find -ls output. If your find … -ls output is different, adjust.

In this version, using the existing directory information (file size) and the built-in ls feature of find should be efficient, avoiding process creations or file i/o.

Solution 2 - Linux

With zsh, you can use extended globbing to do:

du -c **/*.undo

Solution 3 - Linux

find -name *.undo -print0 | du -hc --files0-from=-

Solution 4 - Linux

du -c *pattern*

This will print the total on the last line of output.

Solution 5 - Linux

I have been looking at this problem too (only a year later...) - only just found this page.

Something that I found works (for me) is the following:

find /mnt/iso -name *.avi -printf "%s\n" | paste -sd+ - | bc

This will return the total size of all the .avi files in all the sub-folders below /mnt/iso

I have to give credit to radoulov for the paste command - see this page: https://stackoverflow.com/questions/450799/linux-command-to-sum-integers-one-per-line

Just to add - just in case a folder matches the search term - it's a good idea to use -type f in the find command too.

Solution 6 - Linux

find -name '*.undo' -exec wc -c {} + | tail -n 1

should give the actual total number of bytes in the files, if you don't have too many files (where "too many" is going to be a really large number, probably in the thousands). Or if you just want to get the number alone,

find -name '*.undo' -exec wc -c {} + | tail -n 1 | cut -d' ' -f 1

Solution 7 - Linux

Python is part of most linux distributions.

import os
import fnmatch
size= 0
for path, dirs, files in os.walk( '.' ):
    for f in files:
        if fnmatch.fnmatch(f,'*.py'):
            fileSize= os.path.getsize( os.path.join(path,f) ) 
            print f, fileSize
            size += fileSize
print size

Longish, but perfectly clear and highly extensible.

Solution 8 - Linux

find -name '*.undo' -print0 | du -hc --files0-from=- | tail -n 1

Put together from [gerdemb][1]'s and strager's contributions. Using du -cb should display bytes.

[1]: https://stackoverflow.com/users/27478/gerdemb "gerdemb"

Solution 9 - Linux

I use du command like this to get the number only:

du file_list | awk '{s+=$1} END {print s}'

Solution 10 - Linux

How about this simple one.

find ./ -name *.undo | xargs wc

Solution 11 - Linux

Or, you can just do this:

dir=$1

for file in $dir/* ; do

 length_file=`stat -c %s $file`
 echo "File $file has length $length_file"
 length_total=`expr $length_total + $length_file`

done

echo "Total length: $length_total ."

Where stat displays a file or file system status. The argument -c means using the specified format instead of the default one, and the format sequence $s allows the display of the total size of bytes.

expr 

Just evaluates an expression.

Solution 12 - Linux

Perl one-liner:

find . -name "*.undo" -ls | perl -lane '$t += $F[6]; END{print $t}'

The @F autosplit array starts at index $F[0] while awk fields start with $1, hence $F[6] is used instead of awk's $7

Solution 13 - Linux

du -c | awk '/./{line=$0} END{print $1}'

Solution 14 - Linux

I think the version with xargs could be imroved (simplified) ls -1 *.undo | xargs wc

Solution 15 - Linux

Check the du (disk usage) command.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionyothenbergView Question on Stackoverflow
Solution 1 - LinuxtpgouldView Answer on Stackoverflow
Solution 2 - LinuxChris AtLeeView Answer on Stackoverflow
Solution 3 - LinuxgerdembView Answer on Stackoverflow
Solution 4 - LinuxCantillonView Answer on Stackoverflow
Solution 5 - LinuxT-MonsterView Answer on Stackoverflow
Solution 6 - LinuxDavid ZView Answer on Stackoverflow
Solution 7 - LinuxS.LottView Answer on Stackoverflow
Solution 8 - LinuxxilefView Answer on Stackoverflow
Solution 9 - LinuxHoang NTView Answer on Stackoverflow
Solution 10 - LinuxDennis MathewsView Answer on Stackoverflow
Solution 11 - Linuxbliss_terraView Answer on Stackoverflow
Solution 12 - LinuxChris KoknatView Answer on Stackoverflow
Solution 13 - LinuxPeter CottonView Answer on Stackoverflow
Solution 14 - LinuxJacobView Answer on Stackoverflow
Solution 15 - LinuxChristian C. SalvadóView Answer on Stackoverflow