Printing the sum-size of copied files in bash
Printing the sum-size of copied files in bash
I would like from the code below to print the sum-size of the files being copied instead of the size of each copied file separately.
#!/bin/bash
input_folder=/a/b/c
output_folder=/d/e/f
cd $input_folder
for i in *.tiff; do
size=$(wc -c < $i)
cp -v $i $out | sleep 1 | echo -ne "$size%33[0Kr"
done
This bash prints every second the size of the file being copied.
bash
For example, in second 1 it copies file A and prints the size of file A. In second 2 it copies file B and prints the size of file B instead of the total size of files A+B. In second 3 it copies the file C and prints the size of file C instead of the total size of files A+B+C
1
file A
file A
2
file B
file B
A+B
3
file C
file C
A+B+C
How can I do it in bash specifically?
bash
@ RalfFriedl. Thanks! probably just sleep
0.1 ?– user88036
Sep 9 '18 at 18:21
0.1
4 Answers
4
Just sum up the single sizes and echo it afterwards.
echo
#!/bin/bash
input_folder=/a/b/c
output_folder=/d/e/f
cd $input_folder
size_sum=0
for i in *.tiff; do
size=$(wc -c < $i)
size_sum=$((size_sum + size))
cp -v $i $out | sleep 1
done
echo $size_sum
size=$(wc -c < $i)
This isn't a very smart way to get the size of a file. Running wc like that will involve reading the whole file, which really is completely unnecessary since all you want is the size which the filesystem already knows and can tell you.
wc
This is mitigated by the fact that you copy the file afterwards, and so need to read it in any case. A moderately-sized file will probably stay in the cache for the duration, so the reads don't actually hit the disk. But still, it would seem sensible to just read the size.
With GNU utilities, you can get the size of the file with stat -c %s "$filename". Sadly, the options stat takes are different on other systems, and I don't think there's a better, more portable way (apart from running Perl)
stat -c %s "$filename"
stat
cp -v $i $out | sleep 1 | echo -ne "$size%33[0Kr"
Here, the pipeline seems odd. cp doesn't produce any output (to standard output), at least not without -i, so there's nothing to pipe. Even if it did, sleep doesn't read anything so any output from cp would be wasted. The same thing happens between sleep and echo. This is basically the total opposite of what pipelines are usually used for, but it does have the effect that all the commands run in parallel, and the shell waits for all of them to complete, so that pipeline takes at least one second to run, regardless of how fast the copy would otherwise be.
cp
-i
sleep
cp
sleep
echo
If you want to sum the file sizes, the shell's arithmetic expansion $(( .. )) is what you probably want. So, without any extra sleeps:
$(( .. ))
dest=/path/to/destination
total=0
for file in *.tiff; do
size=$(stat -c %s "$file");
printf "current %d total %dn" "$size" "$((total += size))"
cp -- "$file" "$dest"
done
To save on the arithmetic in your script, you can just take the size of the concatenation of the files:
cat *.tiff | wc
The UN*X kernel will conspire with you to make this just as efficient as taking the sizes of the files separately.
I think this should be
wc -c.– user1934428
Sep 10 '18 at 8:37
wc -c
It is possible to sum with += if the variable is declared as integer:
+=
$ declare -i size
$ size+=100; echo "$size"
100
$ size+=200; echo "$size"
300
Your script (with variable expansions correctly quoted):
#!/bin/bash
input_folder=./a/b/c
output_folder=./d/e/f
declare -i size
for i in "$input_folder"/*; do
size+=$(wc -c < "$i")
cp -v "$i" "$output_folder" | sleep 1 | echo -ne "$size33[0Kr"
done
Thanks for contributing an answer to Unix & Linux Stack Exchange!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You should note that it doesn't print the size every second, it sleeps one second between echo file. If it takes long enough that you want to display some progress, you probably don't want an extra delay.
– RalfFriedl
Sep 9 '18 at 16:31