Calculate file size in shell

I am trying to calculate the total size in bytes of all the files (in the directory tree) matching the file name pattern only using the shell. This is what I still have:

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

Is there an easier way to do this? I feel there should be a simple du or find switch that does this for me, but I cannot find it.

To be clear, I want the files matching the pattern to be under the directory tree, which means

du -bs * .undo

will not work because it only matches files in the current directory.

+51
linux shell
Mar 01 '09 at 0:57
source share
15 answers

Try:

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

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

In this version, the use of existing directory information (file size) and the built-in find function should be efficient, avoiding the creation of processes or file input / output.

+94
Mar 01 '09 at 1:59
source share

With zsh, you can use advanced globbing:

du -c ** / *. undo

+35
Mar 01 '09 at 3:00
source share
 find -name *.undo -print0 | du -hc --files0-from=- 
+22
May 18 '09 at
source share
 du -c *pattern* 

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

+18
Mar 01 '09 at 1:10
source share

I also considered this problem (only after a year ...) - I just found this page.

Something I found works (for me):

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

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

I have to pay tribute to radoulov for the paste command - see this page: Shell command for summing integers, one per line?

Just add - just in case the folder matches the search query - it's nice to also use -type f in the find command.

+9
Jun 09 2018-11-11T00:
source share
 find -name '*.undo' -exec wc -c {} + | tail -n 1 

should indicate the actual total number of bytes in the files if you have too many files (where "too many" will be a really large number, perhaps in thousands). Or, if you just want to get number one,

 find -name '*.undo' -exec wc -c {} + | tail -n 1 | cut -d' ' -f 1 
+8
Mar 01 '09 at 1:16
source share

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 

Long, but completely transparent and very expandable.

+5
Mar 01 '09 at 1:29
source share
 find -name '*.undo' -print0 | du -hc --files0-from=- | tail -n 1 

Team up from gerdemb and guard contributions. Using du -cb should display bytes.

+3
Apr 13 '10 at 11:14
source share

I use the du command to get only the number:

 du file_list | awk '{s+=$1} END {print s}' 
+2
Jul 18 '13 at 18:43
source share

How about this simple.

 find ./ -name *.undo | xargs wc 
0
Feb 08 '13 at 18:50
source share

Or you can simply 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 the status of a file or file system. The -c argument means using the specified format instead of the default value, and the $ s formatting sequence allows the total byte size to be displayed.

 expr 

Just appreciates the expression.

0
Feb 03 '15 at 19:59
source share

Perl Single Line:

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

The autosplit @F array starts at index $F[0] , while awk fields start at $ 1, so $F[6] used instead of awk $7

0
Sep 09 '15 at 17:26
source share

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

0
Jun 14 '16 at 20:52
source share

I think the xargs version can be extended (simplified) ls -1 * .undo | xargs wc

0
May 11 '17 at 16:07
source share

Check du (disk usage).

-3
Mar 01 '09 at 1:04
source share



All Articles