Якщо припустити, що немає внутрішніх жорстких посилань (тобто кожен файл з більш ніж 1 жорсткою посиланням пов'язаний з-за дерева), ви можете:
find . -links -2 -print0 | du -c --files0-from=-
EDIT І ось те, що я замалював у коментарі, застосував. Тільки без du; kudos to @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друкує кількість посилань, кількість inode та використання диска. Ми передаємо цей список, sort | uniq -cщоб отримати список (кількість появи у дереві, кількість посилань, inode, використання диска).
Ми передаємо цей список через awk, і якщо перше поле (кількість показів) більше або дорівнює другому (# твердих посилань), тобто немає посилань на цей файл із-за дерева, а потім надрукуємо четверте поле ( використання диска) зі знаком плюс та додається зворотна косої риски.
Нарешті ми виводимо a 0, тому формула є синтаксично правильною (вона б спричинила +інакше) і передаємо її bc. Phew.
(Але я б застосував простіший перший метод, якщо він дає досить хорошу відповідь.)
duпідраховує розміри файлів лише один раз, навіть якщо вони жорстко пов'язані, якщо ви не використовуєте параметр-l/--count-links. Ви працюєтеduпо всьому дереву двічі, з цією опцією та без неї, а різниця між розмірами повинна бути стільки, скільки ви зберегли в усіх каталогах.