Розмір усіх файлів певного розширення в дереві каталогів


17

Я хочу знати розмір файлу з розширенням .o (об'єктний файл) у своїй домашній папці.

Я можу знайти всі файли об'єктів за допомогою

find . -name '*.o'

Як тепер я можу обчислити загальний розмір цих файлів?

Відповіді:


24

Ви шукаєте труби ( |). Вони є способом з'єднання декількох команд і передачі виводу однієї команди як вхід до іншої. У цьому випадку ви хочете передати всі імена файлів, які ви знайдете як вхідні 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

Існує трохи проблеми з першим. Є таке поняття, як MAXARGS. Таким чином, буде кілька ітерацій du, і це створить кілька totalрядків. Ось приклад: paste.ubuntu.com/23092752
Сергій Колодяжний

@ Сергій правда. Я додав ще один варіант, який уникає цього.
тердон

Ваш перший shopt globstarприклад залишає поза -s; Мені довелося скористатися shopt -s globstarаналогічно вашому другому прикладу.
CrazyPyro

@ CrazyPyro d'oh! Вибачте, це була помилка. Дякуємо, що вказали на це. shopt OPTIONбез -sабо або -u(або іншої опції, див. help shopt) просто друкує поточне значення OPTION. Потрібно shopt -s OPTIONвключити і shopt -u OPTIONвимкнути його.
тердон

8

Використовувати -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

0

з perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

Розмір усіх не прихованих PDF-файлів у поточному каталозі.


1
Гаразд, але ОП шукає .oфайли, і вони можуть бути у підкаталогах. Ви також можете додати }{попереднє значення, print $sumщоб уникнути друку суми за кожну ітерацію. Ми хочемо лише останнього.
тердон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.