Відповіді:
Ви шукаєте труби ( |). Вони є способом з'єднання декількох команд і передачі виводу однієї команди як вхід до іншої. У цьому випадку ви хочете передати всі імена файлів, які ви знайдете як вхідні du(що обчислює розмір). Однак, оскільки duочікує, що назви файлів і результати - findце лише перелік тексту (так, текст складається з назв файлів, але duне можу знати, що все, що він бачить, це текст), вам потрібно використовувати щось на зразок, xargsяке займе кожен рядок тексту, розглядайте його як ім'я файлу та передайте його du. Збираючи все це разом, ми отримуємо:
find . -name "*.o" | xargs du -sch
ви завжди повинні цитувати шаблони, які ви надаєте find(як я це робив вище "*.o":). Якщо цього не зробити, оболонка розшириться *.oдо імен будь-яких відповідних файлів у поточному каталозі. У цьому випадку воно працювало лише тому, що у вас не було відповідних файлів.
Ці -schповертатися duописані в man du:
-c, --total
produce a grand total
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-s, --summarize
display only a total for each argument
Однак зауважте, що це не вдасться для імен файлів, що містять пробіли. Це майже точно не буде проблемою для об’єктних файлів, але в майбутньому, якщо вам також потрібно мати справу з пробілами, використовуйте:
find . -name "*.o" -print0 | xargs -0 du -sch
У -print0марці findдрук NULL розділених рядків і -0марка xargsприймає такі рядки в як вхідні дані.
Крім того, ви можете findроздрукувати самі розміри, а потім підсумувати їх:
find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'
Це також дозволить обійти проблему, згадану @Serg в коментарях, де аргументів занадто багато і команда розбита на окремі команди.
Якщо ви використовуєте bash(напевно, є), є більш простий спосіб:
shopt -s globstar
du -sch **/*.o
У shopt globstarкоманді дозволяє **сполучати всі файли і підкаталогів або більше. Після його ввімкнення **/*.oвідповідатиме всі файли (та каталоги), ім'я яких закінчується .o, тому ми можемо передати це безпосередньо du.
Зауважте, що на відміну від findпідходу, це не буде відповідати прихованим файлам (тим, чиє ім'я починається з а .). Щоб відповідати цим, виконайте:
shopt -s dotglob globstar
du -sch **/*.o
shopt globstarприклад залишає поза -s; Мені довелося скористатися shopt -s globstarаналогічно вашому другому прикладу.
shopt OPTIONбез -sабо або -u(або іншої опції, див. help shopt) просто друкує поточне значення OPTION. Потрібно shopt -s OPTIONвключити і shopt -u OPTIONвимкнути його.
Використовувати -exec прапор для запуску duкоманди з ;(значення кожного файлу)
find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}'
Вибірка зразка:
$ find . -name "*.txt" -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes
findє рекурсивним - означає, що він проходить через усі підкаталоги. Якщо ви просто хочете отримати загальну кількість усіх *.oфайлів у поточному каталозі, просто зробіть це
du -b -c *.o
з perl:
perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf
Розмір усіх не прихованих PDF-файлів у поточному каталозі.
.oфайли, і вони можуть бути у підкаталогах. Ви також можете додати }{попереднє значення, print $sumщоб уникнути друку суми за кожну ітерацію. Ми хочемо лише останнього.
du, і це створить кількаtotalрядків. Ось приклад: paste.ubuntu.com/23092752