Общий размер содержимого всех файлов в каталоге [закрыто]


103

Когда я использую lsили du, я получаю объем дискового пространства, который занимает каждый файл.

Мне нужна общая сумма всех данных в файлах и подкаталогах, которые я получил бы, если бы открыл каждый файл и подсчитал байты. Бонусные баллы, если я смогу получить это, не открывая каждый файл и не подсчитывая.


1
lsфактически показывает количество байтов в каждом файле, а не объем дискового пространства. Этого достаточно для ваших нужд?
Грег Хьюгилл,

3
Обратите внимание, что duнельзя использовать для ответа на этот вопрос. Он показывает объем дискового пространства, который каталог занимает на диске (данные файлов плюс размер метаинформации вспомогательной файловой системы). Результат duможет быть даже меньше, чем общий размер всех файлов. Это может произойти, если файловая система может хранить сжатые данные на диске или если используются жесткие ссылки. Правильные ответы основаны на lsи find. См. Ответы Нельсона и bytepan здесь, или этот ответ: unix.stackexchange.com/a/471061/152606
anton_rh

Ответы:


108

Если вам нужен «видимый размер» (то есть количество байтов в каждом файле), а не размер, занимаемый файлами на диске, используйте параметр -bили --bytes(если у вас есть система Linux с GNU coreutils ):

% du -sbh <directory>

1
работает с моими новыми коробками Red Hat, к сожалению, не с моей встроенной коробкой Dev.
Артур Ульфельдт,

3
Есть ли простой способ показать «видимый размер» в удобочитаемом формате? При использовании du -shb(как было предложено в этом ответе) -bнастройка, похоже, отменяет -hнастройку.
Матиас Байненс

6
@MathiasBynens Поменять порядок флагов на обратный (т.е. du -sbh <dir>). Работает для меня.
Луис Э.

2
@MathiasBynensdu -sh --apparent-size /dir/
Jongosi

2
@Arkady Я пробовал ваше решение на CentOS и Ubuntu, и есть небольшая ошибка. Вы хотите "du -sbh". Флаг "-h" должен быть последним.
theJollySin

46

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

du -sb DIR

При желании добавьте hопцию для более удобного вывода:

du -sbh DIR

4
-b кажется незаконным вариантом для MacOS du
lynxoid

3
@lynxoid: Вы можете установить версию GNU с варевом: brew install coreutils. Он будет доступен как команда gdu.
neu242

1
Не работает. ls-> file.gz hardlink-to-file.gz. stat -c %s file.gz-> 9657212. stat -c %s hardlink-to-file.gz-> 9657212. du -sb-> 9661308. Это определенно не общий размер содержимого, а размер, который каталог занимает на диске.
anton_rh

24

cd в каталог, затем:

du -sh

ftw!

Первоначально об этом писали здесь: https://ao.gl/get-the-total-size-of-all-the-files-in-a-directory/


1
Это просто и работает! Спасибо. Иногда мне нравится добавлять эту -Lопцию по duсимволическим ссылкам.
conradkleinespel

2
у меня работает (на OS X)
Сэм Бусалис 01

2
Это просто и не работает. Он печатает пространство, которое каталог занимает на диске, а не общий размер содержимого, который можно вычислить, открыв каждый файл и подсчитав байты.
anton_rh

17

Просто альтернатива:

ls -lAR | grep -v '^d' | awk '{total += $5} END {print "Total:", total}'

grep -v '^d' исключит каталоги.


4
Отлично, также добавьте параметр -a, чтобы получить «скрытые файлы» (все, что начинается с точки)
Николай

Изолирован для определенного типа файла (в данном случае PNG) и выражен в МБ для большей читаемости: ls -lR | grep '.png$' | awk '{total += $5} END {print "Total:", total/1024/1024, "MB"}'
MusikPolice,

Это правильный ответ. В отличие от duэтого решения действительно подсчитывает общий размер всех данных в файлах, как если бы они были открыты один за другим, и их байты были подсчитаны. Но да, добавление -Aпараметра также необходимо для подсчета скрытых файлов.
anton_rh

13

Формат stat "% s" дает вам фактическое количество байтов в файле.

 find . -type f |
 xargs stat --format=%s |
 awk '{s+=$1} END {print s}'

Не стесняйтесь использовать свой любимый метод суммирования чисел .


4
Предпочтительно использовать "find. -Type f -print0 | xargs -0 ...", чтобы избежать проблем с определенными именами файлов (содержащими пробелы и т. Д.).
hlovdal 06

1
да, хорошее замечание. если бы его не было в bsd 4.2, я не помню, чтобы его использовать :-(
Нельсон

3
find -print0и xargs -0необходимы для имен файлов с пробелами. OS X хочет stat -f %z.
Kornel

1
(Обратите внимание, что stat работает с разреженными файлами, сообщая о большом номинальном размере файла, а не о меньших блоках, используемых на диске, таких как duотчеты.)
Нельсон

1
В отличие от многих других ответов здесь, которые ошибочно используют duутилиту, этот ответ правильный. Здесь очень похоже на ответ: unix.stackexchange.com/a/471061/152606 . Но я бы также использовал ! -type dвместо -type fподсчета символических ссылок (размер самой символической ссылки (обычно несколько байтов), а не размер файла, на который она указывает).
anton_rh

3

Если вы используете "du" busybox в emebedded системе, вы не можете получить точные байты с помощью du, вы можете получить только килобайты.

BusyBox v1.4.1 (2007-11-30 20:37:49 EST) multi-call binary

Usage: du [-aHLdclsxhmk] [FILE]...

Summarize disk space used for each FILE and/or directory.
Disk space is printed in units of 1024 bytes.

Options:
        -a      Show sizes of files in addition to directories
        -H      Follow symbolic links that are FILE command line args
        -L      Follow all symbolic links encountered
        -d N    Limit output to directories (and files with -a) of depth < N
        -c      Output a grand total
        -l      Count sizes many times if hard linked
        -s      Display only a total for each argument
        -x      Skip directories on different filesystems
        -h      Print sizes in human readable format (e.g., 1K 243M 2G )
        -m      Print sizes in megabytes
        -k      Print sizes in kilobytes(default)

3

При создании папки многие файловые системы Linux выделяют 4096 байт для хранения некоторых метаданных о самом каталоге. Это пространство увеличивается кратно 4096 байтам по мере роста каталога.

Команда du (с параметром -b или без него) учитывает это пространство , как вы можете видеть, набрав:

mkdir test && du -b test

у вас будет результат 4096 байт для пустого каталога. Итак, если вы поместите в каталог 2 файла по 10000 байт, общая сумма, указанная du -sb , составит 24096 байт.

Если вы внимательно прочитаете вопрос, то не об этом. Спрашивающий спросил:

общая сумма всех данных в файлах и подкаталогах, которые я получил бы, если бы открыл каждый файл и подсчитал байты

что в приведенном выше примере должно быть 20000 байт, а не 24096.

Итак, правильный ответ IMHO может быть смесью ответа Нельсона и предложения hlovdal для обработки имен файлов, содержащих пробелы:

find . -type f -print0 | xargs -0 stat --format=%s | awk '{s+=$1} END {print s}'

2

Существует как минимум три способа получить «общую сумму всех данных в файлах и подкаталогах» в байтах, которые работают как в Linux / Unix, так и в Git Bash для Windows, и перечислены ниже в порядке от самого быстрого к среднему. Для справки, они выполнялись в корне довольно глубокой файловой системы ( docrootв установке Magento 2 Enterprise, содержащей 71 158 файлов в 30 027 каталогах).

1.

$ time find -type f -printf '%s\n' | awk '{ total += $1 }; END { print total" bytes" }'
748660546 bytes

real    0m0.221s
user    0m0.068s
sys     0m0.160s

2.

$ time echo `find -type f -print0 | xargs -0 stat --format=%s | awk '{total+=$1} END {print total}'` bytes
748660546 bytes

real    0m0.256s
user    0m0.164s
sys     0m0.196s

3.

$ time echo `find -type f -exec du -bc {} + | grep -P "\ttotal$" | cut -f1 | awk '{ total += $1 }; END { print total }'` bytes
748660546 bytes

real    0m0.553s
user    0m0.308s
sys     0m0.416s


Эти два также работают, но они полагаются на команды, которых нет в Git Bash для Windows:

1.

$ time echo `find -type f -printf "%s + " | dc -e0 -f- -ep` bytes
748660546 bytes

real    0m0.233s
user    0m0.116s
sys     0m0.176s

2.

$ time echo `find -type f -printf '%s\n' | paste -sd+ | bc` bytes
748660546 bytes

real    0m0.242s
user    0m0.104s
sys     0m0.152s


Если вам нужна только сумма для текущего каталога, добавьте -maxdepth 1к find.


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

$ du -sbh
832M    .

$ ls -lR | grep -v '^d' | awk '{total += $5} END {print "Total:", total}'
Total: 583772525

$ find . -type f | xargs stat --format=%s | awk '{s+=$1} END {print s}'
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
4390471

$ ls -l| grep -v '^d'| awk '{total = total + $5} END {print "Total" , total}'
Total 968133

1
Что касается Git Bash для Windows, то в случае Cygwin он dcявляется частью bcпакета, поэтому дляdc его получения необходимо установить bc.
ruvim

1

Для Win32 DOS вы можете:

c:> каталог / sc: \ каталог \ вы \ хотите

а в предпоследней строке будет указано, сколько байтов занимают файлы.

Я знаю, что это читает все файлы и каталоги, но в некоторых ситуациях работает быстрее.


1

duудобно, но findполезно в том случае, если вы хотите рассчитать размер только некоторых файлов (например, используя фильтр по расширению). Также обратите внимание, что findсами могут распечатать размер каждого файла в байтах. Чтобы рассчитать общий размер, мы можем подключить dcкоманду следующим образом:

find . -type f -printf "%s + " | dc -e0 -f- -ep

Здесь findформируется последовательность команд для dcлайка 123 + 456 + 11 +. Хотя, готовая программа должна быть похожей 0 123 + 456 + 11 + p(вспомним постфиксную нотацию).

Итак, чтобы получить законченную программу, нам нужно поместить ее 0в стек перед выполнением последовательности из стандартного ввода-вывода и вывести верхнее число после выполнения ( pкоманда в конце). Мы достигаем этого с помощью dcопций:

  1. -e0просто ярлык для того, -e '0'чтобы положить его 0в стек,
  2. -f-предназначен для чтения и выполнения команд из stdin (сгенерированных findздесь),
  3. -epпредназначен для печати результата ( -e 'p').

Чтобы напечатать размер в MiB, как 284.06 MiBмы можем использовать -e '2 k 1024 / 1024 / n [ MiB] p'вместо этого в пункте 3 (большинство пробелов необязательны).


1

Это может помочь:

ls -l| grep -v '^d'| awk '{total = total + $5} END {print "Total" , total}'

Приведенная выше команда суммирует все файлы, покидающие размер каталогов.


1
Обратите внимание, что это решение очень похоже на ответ Баруна. Но это решение не суммирует файлы в подкаталогах.
ruvim 02 окт.15,

1
@ruvim, он также не суммирует скрытые файлы. Для суммирования скрытых файлов -Aнеобходимо добавить параметр в ls.
anton_rh

0

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

$ du -ckx <DIR> | grep total | awk '{print $1}'

Где <DIR> - это каталог, который вы хотите проверить.

'-C' дает вам общие данные, которые извлекаются с помощью части команды 'grep total', а количество в килобайтах извлекается с помощью команды awk.

Единственное предостережение: если у вас есть подкаталог, содержащий текст «total», он также будет выплевывать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.