Supondo que não haja links físicos internos (ou seja, todo arquivo com mais de um link físico esteja vinculado de fora da árvore), você pode:
find . -links -2 -print0 | du -c --files0-from=-
EDIT E aqui está o que eu esboçado no comentário, aplicado. Somente sem du
; parabéns a @StephaneChazelas para perceber que du
não é necessário. Explicação no final.
( find . -type d -printf '%k + ' ; \
find . \! -type d -printf '%n\t%i\t%k\n' | \
sort | uniq -c | \
awk '$1 >= $2 { print $4 " +\\" }' ; \
echo 0 ) | bc
O que fazemos é criar uma string com o uso do disco (em KB) de cada arquivo relevante, separado por sinais de adição. Então alimentamos essa grande adição a bc
.
A primeira find
chamada faz isso para diretórios.
A segunda find
imprime a contagem de links, o inode e o uso do disco. Passamos essa lista sort | uniq -c
para obter uma lista de (número de aparências na árvore, contagem de links, inode, uso do disco).
Passamos essa lista awk
e, se o primeiro campo (número de aparências) for maior ou igual ao segundo (número de hardlinks), o que significa que não há links para esse arquivo de fora da árvore e imprima o quarto campo ( uso de disco) com um sinal de adição e uma barra invertida anexada.
Finalmente, produzimos a 0
, portanto a fórmula está sintaticamente correta (seria en +
caso contrário) e a passamos para bc
. Ufa.
(Mas eu usaria o primeiro método mais simples, se ele der uma resposta boa o suficiente.)
du
conta apenas os tamanhos de arquivo uma vez, mesmo se eles estiverem vinculados, a menos que você use a opção-l
/--count-links
. Você executadu
a árvore inteira duas vezes, com e sem essa opção e a diferença entre os tamanhos deve ser a quantidade de espaço que você salvou em todos os diretórios.