Rainysky
Rainysky

Reputation: 887

How to add up all the total file size of individual .txt files?

I am not sure how to add up the file sizes, I am able to find the file name, each individual size of the file but for total file I am not sure about it

Code:

if [ $numberof_files -ge 3 ]; then
    for file in "${txt_files[@]}"; do
        size=$(stat -c%s "$file")
        echo "filename: $file"
        echo "size: $size bytes"
    done
fi

Upvotes: 3

Views: 130

Answers (3)

LMC
LMC

Reputation: 12822

It exists a Linux command for that: du (man du - estimate file space usage). Part of the coreutils package in almost every distro.

total_size=$(du -b --total *.txt | tail -n1 | cut -f1)
echo "$total_size"

Result

159777

Units could also be kilobytes (-k) or megabytes (-m)

du -k --total *.txt
156     irresp-pts.txt
4       requirements-3.9.txt
4       tmp.txt
164     total

With filenames in an array

a=( f1.txt f2.txt tmp.txt )
du -b --total ${a[*]} | tail -n1 | cut -f1

Upvotes: 0

Arkadiusz Drabczyk
Arkadiusz Drabczyk

Reputation: 12528

You can use Bash arithmetic expansion to calculate the total size on the fly:

if [ $numberof_files -ge 3 ]; then

for file in "${txt_files[@]}"; do
    size=$(stat -c%s "$file")
    echo "filename: $file"
    echo "size: $size bytes"
    total_size=$((total_size + size))
done

echo total_size: "$total_size"

fi

There is no need to explicitly initialize total_size before first use because as we read in man bash under ARITHMETIC EVALUATION:

A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax.

Upvotes: 7

markp-fuso
markp-fuso

Reputation: 35256

Populating the array:

declare -a txt_files=([0]="test.txt" [1]="sample.txt" [2]="z y x.txt")

Using stat to display each file's size (in bytes) and name:

$ stat -c'%s|%n' "${txt_files[@]}"
26|test.txt
21|sample.txt
22|z y x.txt

Feeding the stat call to a bash/while read loop while maintaining a running total of all bytes:

total_bytes=0

while IFS='|' read -r size fname
do
    printf "filename: %s\nsize: %d bytes\n\n" "${fname}" "${size}"
    (( total_bytes+=size ))
done < <(stat -c'%s|%n' "${txt_files[@]}")

echo "total: ${total_bytes} bytes"

An alternative where we feed the stat call to an awk script:

awk -F'|' '
    { printf "filename: %s\nsize: %d bytes\n\n", $2, $1
      total_bytes += $1
    }
END { print "total:", total_bytes, "bytes" }
' < <(stat -c'%s|%n' "${txt_files[@]}")

These both generate:

filename: test.txt
size: 26 bytes

filename: sample.txt
size: 21 bytes

filename: z y x.txt
size: 22 bytes

total: 69 bytes

Upvotes: 3

Related Questions