Использование диском файлов, чьи имена соответствуют регулярному выражению, в Linux? - PullRequest
38 голосов
/ 28 февраля 2012

Итак, во многих ситуациях мне нужен был способ узнать, какая часть моего дискового пространства используется для чего, поэтому я знаю, от чего избавиться, преобразовать в другой формат, хранить в другом месте (например, на DVD с данными), перейти кдругой раздел и т. д. В этом случае я смотрю на раздел Windows с загрузочного носителя SliTaz Linux .

В большинстве случаев мне нужен размер файлов и папок,и для этого я использую основанные на NCurses ncdu :

ncdu

Но в этом случае мне нужен способ получить размер все файлы, соответствующие регулярному выражению .Пример регулярного выражения для файлов .bak:

.*\.bak$

Как получить эту информацию, учитывая стандартный Linux с основными утилитами GNU или BusyBox ?

Редактировать: Вывод предназначен для анализа сценарием.

Ответы [ 6 ]

44 голосов
/ 28 февраля 2012

Я предлагаю что-то вроде: find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1

Некоторые заметки:

  • Опция -print0 для find и --files0-from для du позволяет избежать проблем с пробелами в именах файлов
  • Регулярное выражение сопоставляется со всем путем, например ./dir1/subdir2/file.bak, а не просто file.bak, поэтому, если вы измените его, примите это во внимание
  • Я использовал флаг h для du, чтобы создать «читаемый человеком» формат, но если вы хотите проанализировать вывод, вам может быть лучше использовать k (всегда используйте килобайты)
  • Если вы удалите команду tail, вы дополнительно увидите размеры отдельных файлов и каталогов

Sidenote: хороший графический инструмент для определения того, кто съел ваше дисковое пространство: FileLight . Он не выполняет регулярные выражения, но очень удобен для поиска больших каталогов или файлов, забивающих ваш диск.

23 голосов
/ 10 июля 2012

du мой любимый ответ.Если у вас фиксированная структура файловой системы, вы можете использовать:

du -hc *.bak

Если вам нужно добавить подкаталоги, просто добавьте:

du -hc *.bak **/*.bak **/**/*.bak

и т. Д. И т. Д.

Однако,это не очень полезная команда, поэтому используйте команду find:

TOTAL=0;for I in $(find . -name \*.bak); do  TOTAL=$((TOTAL+$(du $I | awk '{print $1}'))); done; echo $TOTAL

Это отобразит общий размер в байтах всех найденных вами файлов.

Надеюсь, это поможет.

3 голосов
/ 11 декабря 2012

Предыдущие решения не работали для меня должным образом (у меня были проблемы с конвейером du), но следующие работали отлично:

find path/to/directory -iregex ".*\.bak$" -exec du -csh '{}' + | tail -1

Параметр iregex является регистронезависимым регулярным выражением. Используйте regex, если хотите, чтобы он был чувствительным к регистру.

Если вам не нравятся регулярные выражения, вы можете использовать флаги iname или name (первые не чувствительны к регистру):

find path/to/directory -iname "*.bak" -exec du -csh '{}' + | tail -1

В случае, если вам нужен размер каждого совпадения (а не просто общая сумма), просто пропустите команду piped tail:

find path/to/directory -iname "*.bak" -exec du -csh '{}' +

Эти подходы позволяют избежать проблемы с подкаталогами в ответе @MaddHackers.

Надеюсь, что это поможет другим в той же ситуации (в моем случае, найти размер всех DLL в .NET-решении).

3 голосов
/ 28 февраля 2012

Запустите это в Bourne Shell, чтобы объявить функцию, которая вычисляет сумму размеров всех файлов, соответствующих шаблону регулярных выражений в текущем каталоге:

sizeofregex() { IFS=$'\n'; for x in $(find . -regex "$1" 2> /dev/null); do du -sk "$x" | cut -f1; done | awk '{s+=$1} END {print s}' | sed 's/^$/0/'; unset IFS; }

(В качестве альтернативы вы можете поместить его в скрипт.)

Использование:

cd /where/to/look
sizeofregex 'myregex'

Результатом будет число (в КиБ), включая 0 (если нет файлов, соответствующих вашему регулярному выражению).

Если вы не хотите, чтобы он просматривался в других файловых системах (скажем, вы хотите искать все файлы .so в /, который является монтированием /dev/sda1, но не в /home, который является смонтировать /dev/sdb1, добавить параметр -xdev к find в функции выше.

1 голос
/ 18 апреля 2017

В принятом ответе предлагается использовать

find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1

, но это не работает в моей системе, поскольку du не знает опции --files-0-from в моей системе.Только GNU du знает эту опцию, она не является частью POSIX Standard (поэтому вы не найдете ее во FreeBSD или macOS), и при этом вы не найдете ее в системах на базе BusyBox Linux (например, большинство встроенных систем Linux) или любая другая система Linux, которая не использует версию GNU du.

Тогда есть ответ, предлагающий использовать:

find path/to/directory -iregex .*\.bak$ -exec du -csh '{}' + | tail -1

Это решениебудет работать до тех пор, пока не будет найдено слишком много файлов, так как + означает, что find попытается вызвать du с максимально возможным количеством обращений за один вызов, однако может быть максимальное количество аргументов(N) система поддерживает, и если будет больше совпадений, чем это значение, find будет вызывать du несколько раз, разбивая попадания на группы, меньшие или равные N элементов каждый, и в этом случае результат будет неправильным и толькопокажите размер последнего du вызова.

Наконец, есть ответ, использующий stat и awk, который является хорошим способом сделать это, но он использует глобализацию оболочки таким образом, чтотолько Баш4.x или более поздняя поддержка.Он не будет работать со старыми версиями и, если он работает с другими оболочками, непредсказуем.

Решение, соответствующее POSIX (работает в Linux, macOS и любых вариантах BSD), которое не страдает какими-либо ограничениями и будетнаверняка работа с каждой оболочкой будет:

find . -regex '.*\.bak' -exec stat -f "%z" {} \; | awk '{s += $1} END {print s}'
1 голос
/ 29 февраля 2012

Если вы в порядке с шаблонами глобуса и вас интересует только текущий каталог:

stat -c "%s" *.bak | awk '{sum += $1} END {print sum}'

или

sum=0
while read size; do (( sum += size )); done < <(stat -c "%s" *.bak)
echo $sum

Директива %s для stat дает байты, а не килобайты.

Если вы хотите спуститься в подкаталоги, в bash версии 4 вы можете shopt -s globstar и использовать шаблон **/*.bak

...