Предполагая, что нет внутренних жестких ссылок (то есть каждый файл с более чем одной жесткой ссылкой связан вне дерева), вы можете сделать:
find . -links -2 -print0 | du -c --files0-from=-
РЕДАКТИРОВАТЬ И вот что я набросал в комментарии, применил. Только без du; Слава @StephaneChazelas для замечаний duне нужна. Объяснение в конце.
( 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
Что мы делаем, это создаем строку с использованием диска (в КБ) каждого соответствующего файла, разделенных знаком плюс. Затем мы кормим это большое дополнение к bc.
Первый find вызов делает это для каталогов.
Второй findвыводит количество ссылок, индекс и использование диска. Мы передаем этот список черезsort | uniq -c чтобы получить список (количество появлений в дереве, количество ссылок, индекс, использование диска).
Мы передаем этот список черезawk , и, если первое поле (количество появлений) больше или равно второму (количество жестких ссылок), то есть нет ссылок на этот файл извне дерева, выведите четвертое поле ( использование диска) со знаком плюс и обратной косой чертой.
Наконец, мы выводим a 0, поэтому формула синтаксически верна (в +противном случае это будет en ) и передаем ееbc . Уф.
(Но я бы использовал более простой первый метод, если он дает достаточно хороший ответ.)
duсчитает размеры файлов только один раз, даже если они жестко связаны, если вы не используете параметр-l/--count-links. Вы запускаетеduвсе дерево дважды с этой опцией и без нее, и разница между размерами должна заключаться в том, сколько места вы сэкономили во всех каталогах.