Як знайти файли та загальний розмір?


12

Я хотів би знайти серію файлів (на основі виразного виразу) та загальне їх використання на диску.

Щось на зразок цього:

$ find . -name 'flibble*' -ctime +90 -exec du -sh {} \;

2.1G    ./flibble_116.log
2.1G    ./flibble_83.log
2.1G    ./flibble_211040_157.log
2.1G    ./flibble3747_51.log

Ця робота. Але це не дає результату, який я шукаю. У ньому перераховано простір, який використовує кожен файл, як findі повторюється через них.

Те, що я хочу, - це загальна кількість duвсіх знайдених файлів.

Відповіді:


12

Рішення

Надаючи опцію -c(або --total) до du(1), ви можете доручити їй отримати загальну суму. Якщо ваша реалізація du(1)підтримує будь-який з цих параметрів, ви можете досягти бажаного ефекту, використовуючи наступну команду:

$ find . -name 'flibble*' -ctime +90 -exec du -shc {} +

EDIT: Зауважте, що якщо кількість файлів перевищує максимальну кількість параметрів, дозволених вашою системою, findвони все одно можуть виконуватися commandкілька разів. Деякі реалізації du(1)також підтримують зчитування імен файлів з файлу, який не страждає від згаданого обмеження:

$ find -name 'flibble*' -ctime +90 -print0 > filenames
$ du -shc --files0-from=filenames

Пояснення

Різниця між семантикою -exec command {} \;та та -exec command {} +полягає в наступному:

  • command {} \;виконується commandодин раз для кожного результату find. Ім'я результату результату передається замість {}.

    $ touch 1 2 3
    $ find  1 2 3 -maxdepth 0 -exec echo {} \;
    1
    2
    3
  • command {} +виконує command, коли всі результати були знайдені. Назви результатів передаються замість {}.

    $ touch 1 2 3
    $ find  1 2 3 -maxdepth 0 -exec echo {} +
    1 2 3

Цей -print0параметр викликає find(1)друк знайдених імен файлів на стандартний висновок, розділений нульовим символом, а --files0-fromпараметр викликає du(1)зчитування розділених нулем імен файлів. На відміну від нового символу рядка, нульовий символ може не відображатися в імені файлу, тому вихід є однозначним.

Щоб дізнатися більше про варіанти du(1)та find(1), вам слід проконсультуватися з відповідними підручниками:

$ man du
$ man find

2
Якщо кількість файлів важлива (1K +), через обмеження кількості аргументів командного рядка, ви можете отримати кілька підсумків.
ychaouche

Я можу підтвердити @ychaouche, я отримав проблему під час спроби оцінити розмір понад 30 К файлів.
Адріан Н

Якщо це проблема, деякі реалізації du(1)також підтримують читання імен файлів з файлу find 1 2 3 -maxdepth 0 -print0 > filenames; du -shc --files0-from=filenames.
Вітіко

4

Спробуйте це:

du -c `find . -name 'flibble*' -ctime +90` | tail -1

Оригінальна команда дає один аргумент, потім виконує його, поки не пройде всі аргументи. Таким чином, ви просто даєте всі аргументи одразу, потім вирізавши окремі розміри і залишаючи лише загальний. Ви можете видалити трубу та хвіст, щоб показати розмір кожного файлу, якщо хочете.


Це не дасть правильних результатів із іменами шляхів, що містять пробіли. Правильний спосіб зробити це, використовуючи -exec du -c {} +параметр find, який передасть імена шляхів без змін du.
Вітіко

4

Ви можете спробувати це:

find . -name 'flibble*' -ctime +90 -exec du -ch {} + | grep total

2

Я б findсам роздрукував розмір і використав інший інструмент для обчислення загальної кількості:

find . -name 'flibble*' -ctime +90 -printf "%s\n" |
perl -lnE '$sum += $_} END {say $sum'

Якщо ви також хочете побачити імена файлів:

find . -name 'flibble*' -ctime +90 -printf "%s\t%p\n" |
perl -apE '$sum += $F[0]} END {say $sum'

1

Один вкладиш, який повинен працювати для отримання загальної кількості гігабайт в більшості систем:

echo "$(( ($(find . -name 'flibble*' -ctime +90 -type f -printf '%k+' )0)/1024/1024 )) GB"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.