Calcula a soma de vários tamanhos de arquivos no Bash

6

Eu tenho uma lista de arquivos em um arquivo, cache_temp .

No arquivo cache_temp :

/home/maildir/mydomain.com/een/new/1491397868.M395935P76076.nm1.mydomain.com,S=1740,W=1777
/home/maildir/mydomain.com/een/new/1485873821.M199286P14170.nm1.mydomain.com,S=440734,W=446889
/home/maildir/mydomain.com/td.pr/cur/1491397869.M704928P76257.nm1.mydomain.com,S=1742,W=1779:2,Sb
/home/maildir/mydomain.com/td.pr/cur/1501571359.M552218P73116.nm1.mydomain.com,S=1687,W=1719:2,Sa
/home/maildir/mydomain.com/td.pr/cur/1498562257.M153946P22434.nm1.mydomain.com,S=1684,W=1717:2,Sb

Eu tenho um script simples para obter o tamanho dos arquivos em cache_temp :

#!/bin/bash

for i in 'grep -v ^# ~/cache_temp | grep -v "dovecot.index.cache"'; do
    if [ -f "$i" ]; then
        size=$(du -sh "$i" | awk '{print $1}')
        echo $size
    fi
done

Eu tenho uma lista de tamanhos de arquivos:

4,0K
4,0K
4,0K
432K
4,0K

Como posso calcular a soma deles?

    
por Piduna 12.12.2017 / 15:21

5 respostas

5

Use stat em vez de du :

#!/bin/bash

for i in 'grep -v ^# ~/cache_temp | grep -v "dovecot.index.cache"'; do
     [ -f "$i" ] && totalsize=$[totalsize + $(stat -c "%s" "$i")]
done
echo totalsize: $totalsize bytes
    
por 12.12.2017 / 15:29
6

De acordo com du (1), existe uma opção -c cuja finalidade é produzir o total geral.

% du -chs * /etc/passwd
92K ABOUT-NLS
196K    NEWS
12K README
48K THANKS
8,0K    TODO
4,0K    /etc/passwd
360K    total
    
por 12.12.2017 / 17:52
5

Se você precisar usar o arquivo, esse snippet será eficiente.

xargs -a cache_file stat --format="%s" | paste -sd+ | bc -l

O xargs é para evitar o limite de argumentos, mas o número máximo de arquivos em uma invocação de stat de cada vez.

    
por 12.12.2017 / 15:30
4

Se você remover o sinalizador "-h" do seu comando "du", obterá os tamanhos brutos dos bytes. Você pode adicioná-los com a sintaxe ((a += b)) :

a=0
for i in $(find . -type f -print0 | xargs -0 du -s | awk {'print $1'})
do
  ((a += i))
done
echo $a

Os sinalizadores -print0 e -0 para localizar / xargs usam sequências terminadas com nulo para preservar o espaço em branco.

EDIT: Acontece que eu digito mais devagar do que os comentários do @HBruijn!

    
por 12.12.2017 / 15:30
2

Bem ... Para melhor ou pior, aqui está minha implementação disso. Eu sempre preferi usar "while" para ler linhas de arquivos.

#!/bin/bash

SUM=0
while read file; do
    SUM=$(( $SUM + $(stat $file | awk '/Size:/ { print $2 }') ))
done < cache_temp
echo $SUM

Por recomendação de janos abaixo:

#!/bin/bash

while read file; do
    stat $file
done < cache_temp | awk 'BEGIN { s=0 } $1 == "Size:" { s=s+$2 } END  { print s; }'
    
por 12.12.2017 / 15:47