If your using find to its max extent, by using it as a selector tool of wide versatility, then your on the right path. Find is one of the strongest tools in linux. I have many more articles on find. Some may even cover this topic. However I believe I just came across a really simple way of doing something, that I might of showed you how to do in another article. Its important to understand find -exec features. -exec will run a command on a file. -exec has 2 modes that I know of.
The first mode is if you close -exec with a \; , that will run the command listed in -exec once on each file found. So if you found 10 files it will run the command in -exec 10 times, each time running the command with the other file filling up the variable {} . {} is just a place holder for find to put the filename when you use the -exec feature of find. Look below for an example of find using the feature -exec in the mode that ends with \;.
The second mode is if you close -exec with a + , that will run the command listed in -exec only once and not per file (every file found will be listed in the command list). So if you found 10 files it will run the command -exec only once, the single time it runs it, every file that it found will be listed where you put the {} placeholder (in between each file there will be a space). Look below for an exaple of find using the feature -exec in the mode that ends with +, actually the main topic of this article “using find to calculate the size of found files” will use this mode.
Also its important to know that {} in both cases will be correctly escaped for spaces, so if the file it found had spaces like This file.txt , it will automatically do it like this ‘This file.txt’ , or like this “This file.txt” , or like this This\ file.txt
MAIN EXAMPLE
Running it correctly with mode2 +
find . -type f -iwholename "*sample*" -exec du -ch {} +
or
find -type f -iwholename "*sample*" -exec du -ch {} +
The above just looked thru the current folder recursively (you can do it by telling it the current folder with a . or not – it will assume current folder). Then I told it to find all files that have “sample” in the fullpath (yes, im deleting sample videos). Then I told it to line up all the output one after another and stick it into the “du -ch” command. -h gives me human readable sizes. -c gives me a total. And since all of the files are on the same commmand, -c can give me that total. Because I used -exec du -ch {} + instead of -exec du -ch \; it will run one command of du (With all of the files as arguments after the -ch, right where you see {}, each file will have a space inbetween each other, thats what the + feature of -exec in find does)
So if my output found
sample1, sample2, and sample3. Then this:
find . -type f -iwholename "*sample*" -exec du -ch {} +
Would run this:
du -ch sample1 sample2 sample3
which gives me the size of sample1,2 and3, and their cumulative total size together.
Running it incorrectly with mode1 \;
If I instead ran (-exec ending with \; ):
find . -type f -iwholename "*sample*" -exec du -ch {} \;
Then it would run something like this:
du -ch sample1 du -ch sample2 du -ch sample3
Which would give me the size of sample1,2 and 3. But not their totals.
Remember -c gives totals with du . So realistically if we are running find as we are above with \; , we probably didnt want totals, and we wouldnt want the result and the total printed for each file. So instead we would run it like this:
find . -type f -iwholename "*sample*" -exec du -h {} \;
So that it ran something like this
du -h sample1 du -h sample2 du -h sample3
Remember also that with -exec , + concats the results between space, and \; repeats the command on a new line.
WHERE TO NOW
You can use find to find any files or folders you want. And then get the total size of what you just found.
Our Example
For example I ran the command: find . -type f -iwholename “*sample*” -exec du -ch {} +
And I found like 10 or 15 files, that are all these sample video files that I dont want, and it told me they take up 500 MB total. (each one being like 50 MB). So I decided to delete them like this:
find . -type f -iwholename "*sample*" -delete