tags:

views:

152

answers:

4

The command tries to sum up the sizes:

find . -iname "*.dmg" -exec du -sh '{}' \; 3&> /dev/null |
    awk '{print $1}' | summming_up_program???

Can you find a simpler solution?

Ubuntu Solution. Thanks for the Awk-end to Ayman.

find . -iname "*.dmg" -printf '%b\n' |
    awk 'BEGIN { s = 0 } {s += $1 } END { print "%dMB", s / 2^20 }'
+2  A: 
find . -iname '*.dmg' -exec stat -f '%z' '{}' \; |
     awk 'BEGIN { s = 0 } {s += $1 } END { print s }'

stat is used to obtain the size of a file. awk is used to sum all file sizes.

Edit:

A solution that does not fork stat:

find . -iname '*.dmg' -ls | 
     awk 'BEGIN { s = 0 } {s += $7 } END { print s }'
Ayman Hourieh
This forks stat N times where N is the number of files. Bad.
Reef
While this is true, `stat` retrieves the size from the file's inode. This should be much better than `wc` which scans the whole file. Also, this approach works for files in subdirectories.
Ayman Hourieh
`wc` doesn't scan the whole file, if You specify the filenames on the command line. See my answer for details. +1, I think the latter is the most efficient solution possible in bash.
Reef
A: 
Matthias Wandel
Can you explain why the results are so much different with the two commands: 1........ cat file | wc -c 2......... du file...........?
Masi
du measures usage on disk.du would have been the obvious answer, but I assumed you wanted to know the total bytes in the files (that's what the complicated method does).
Matthias Wandel
+1  A: 
wc -c *.pyc | tail -n1 | cut -f 1 -d ' '

Might be faster then cat'ing the files through the pipe. wc -c does not count the bytes, it retrieves the size from inode... or my hdd has a reading speed of 717 GB/s :-)

$ time wc -c very-big.pcap
5394513291 very-big.pcap
real    0m0.007s
user    0m0.000s
sys     0m0.000s
Reef
This does not work for files in subdirectories like `find` does.
Ayman Hourieh
Also, `wc` scans the whole file to find its size. `stat` retrieves the size from the file's inode, which should be much faster.
Ayman Hourieh
I agree about not working for subdirectories, but wc does not literally count the bytes when given a list of files (it does count it, however, if You cat the file through the pipe). I have edited the answer to provide proof.
Reef
+1, thanks for testing. The source code of the `wc` implementation I looked at isn't smart enough to check the inode if you only request `-c`.
Ayman Hourieh
Also, I've edited my answer to add a solution that does not fork `stat`.
Ayman Hourieh
A: 

Enhanced Ayman's non-forking command:

find . -iname '*.dmg' -ls 3&> /dev/null | 
      awk 'BEGIN { s = 0 } {s += $7 } END { print "%dGB", s / 2^30 }'

Thanks to Ayman for correcting my initial reply.

Masi
To append GB to the size, use: find . -iname '*.dmg' -ls | awk 'BEGIN { s = 0 } {s += $7 } END { printf "%dGB\n", s / 2^30 }'
Ayman Hourieh