Tamanho total do conteúdo de todos os arquivos em um diretório [fechado]

103

Quando eu uso lsou du, obtenho a quantidade de espaço em disco que cada arquivo está ocupando.

Preciso da soma total de todos os dados em arquivos e subdiretórios que obteria se abrisse cada arquivo e contasse os bytes. Pontos de bônus se eu conseguir sem abrir cada arquivo e contar.

Arthur Ulfeldt
fonte
1
lsrealmente mostra o número de bytes em cada arquivo, não a quantidade de espaço em disco. Isso é suficiente para suas necessidades?
Greg Hewgill
3
Observe que dunão pode ser usado para responder a esta pergunta. Mostra a quantidade de espaço em disco que o diretório ocupa no disco (os dados dos arquivos mais o tamanho da meta-informação do sistema de arquivos auxiliar). A dusaída pode ser ainda menor do que o tamanho total de todos os arquivos. Isso pode acontecer se o sistema de arquivos puder armazenar dados compactados no disco ou se links físicos forem usados. As respostas corretas são baseadas em lse find. Veja as respostas de Nelson e bytepan aqui, ou esta resposta: unix.stackexchange.com/a/471061/152606
anton_rh

Respostas:

108

Se você quiser o 'tamanho aparente' (que é o número de bytes em cada arquivo), não o tamanho ocupado pelos arquivos no disco, use a opção -bou --bytes(se você tiver um sistema Linux com GNU coreutils ):

% du -sbh <directory>
Arkady
fonte
1
funciona nas minhas novas caixas de chapéu vermelho, infelizmente não na minha caixa de Dev incorporada.
Arthur Ulfeldt
3
Existe uma maneira fácil de mostrar o “tamanho aparente” em formato legível? Ao usar du -shb(conforme sugerido por esta resposta), a -bconfiguração parece substituir a -hconfiguração.
Mathias Bynens
6
@MathiasBynens Inverta a ordem dos sinalizadores (ou seja, du -sbh <dir>). Funciona para mim.
Luis E.
2
@MathiasBynensdu -sh --apparent-size /dir/
Jongosi
2
@Arkady Eu tentei sua solução no CentOS e Ubuntu, e há um pequeno erro. Você quer "du -sbh". A bandeira "-h" deve vir por último.
theJollySin
46

Use du -sb:

du -sb DIR

Opcionalmente, adicione a hopção para uma saída mais amigável:

du -sbh DIR
roubar
fonte
4
-b parece ser uma opção ilegal para MacOS 'du
lynxoid
3
@lynxoid: Você pode instalar a versão GNU com bebida: brew install coreutils. Ele estará disponível como o comando gdu.
neu242
1
Não funciona. ls-> file.gz hardlink-to-file.gz. stat -c %s file.gz-> 9657212. stat -c %s hardlink-to-file.gz-> 9657212. du -sb-> 9661308. Definitivamente, não é o tamanho total do conteúdo, mas o tamanho que o diretório ocupa no disco.
anton_rh
24

cd para o diretório, então:

du -sh

ftw!

Escreveu originalmente sobre isso aqui: https://ao.gl/get-the-total-size-of-all-the-files-in-a-directory/

AO_
fonte
1
Isso é simples e funciona! Obrigado. Às vezes, gosto de adicionar a -Lopção para duseguir os links simbólicos.
conradkleinespel de
2
funciona para mim (no OS X)
sam boosalis
2
Isso é simples e não funciona. Ele imprime o espaço que o diretório ocupa no disco, não o tamanho total do conteúdo que pode ser calculado abrindo cada arquivo e contando os bytes.
anton_rh
17

Apenas uma alternativa:

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

grep -v '^d' irá excluir os diretórios.

Barun
fonte
4
Perfeito, adicione também o parâmetro -a para obter "arquivos ocultos" (qualquer coisa que comece com um ponto)
Nicholi,
Isolado em um tipo de arquivo específico (neste caso, PNG) e expresso em MB para maior legibilidade: ls -lR | grep '.png$' | awk '{total += $5} END {print "Total:", total/1024/1024, "MB"}'
MusikPolice
É uma resposta correta. Ao contrário dudesta solução realmente conta o tamanho total de todos os dados em arquivos como se eles fossem abertos um a um e seus bytes fossem contados. Mas sim, adicionar o -Aparâmetro também é necessário para contar arquivos ocultos.
anton_rh
13

O formato "% s" do stat fornece o número real de bytes em um arquivo.

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

Sinta-se à vontade para substituir a soma dos números pelo seu método favorito .

Nelson
fonte
4
De preferência, use "find. -Type f -print0 | xargs -0 ..." para evitar problemas com certos nomes de arquivo (contendo espaços, etc.).
hlovdal
1
sim, bom ponto. se não estivesse no bsd 4.2, não me lembro de usar :-(
Nelson
3
find -print0e xargs -0são necessários para nomes de arquivos com espaços. OS X quer stat -f %z.
Kornel
1
(Observe que stat funciona com arquivos esparsos, relatando o grande tamanho nominal do arquivo e não os blocos menores usados ​​no disco como durelatórios.)
Nelson
1
Ao contrário de muitas outras respostas aqui que usam erroneamente o duutilitário, esta resposta está correta. É muito semelhante à resposta aqui: unix.stackexchange.com/a/471061/152606 . Mas eu usaria em ! -type dvez de -type fpara contar links simbólicos também (o tamanho do link simbólico em si (geralmente alguns bytes), não o tamanho do arquivo para o qual ele aponta).
anton_rh
3

Se você usar o "du" do busybox no sistema integrado, você não pode obter bytes exatos com du, apenas Kbytes que você pode obter.

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)
Sam Liao
fonte
3

Quando uma pasta é criada, muitos sistemas de arquivos Linux alocam 4096 bytes para armazenar alguns metadados sobre o próprio diretório. Esse espaço é aumentado em um múltiplo de 4096 bytes conforme o diretório cresce.

O comando du (com ou sem a opção -b) leva em conta este espaço , como você pode ver digitando:

mkdir test && du -b test

você terá um resultado de 4096 bytes para um diretório vazio. Portanto, se você colocar 2 arquivos de 10.000 bytes dentro do dir, a quantidade total fornecida por du -sb será de 24096 bytes.

Se você ler atentamente a pergunta, não é isso que pergunta. O questionador perguntou:

a soma total de todos os dados em arquivos e subdiretórios que obteria se abrisse cada arquivo e contasse os bytes

que no exemplo acima deve ter 20.000 bytes, não 24096.

Portanto, a resposta correta IMHO poderia ser uma mistura de resposta de Nelson e sugestão hlovdal para lidar com nomes de arquivos contendo espaços:

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

Existem pelo menos três maneiras de obter a "soma total de todos os dados em arquivos e subdiretórios" em bytes que funcionam tanto no Linux / Unix quanto no Git Bash para Windows, listados abaixo da média mais rápida para a mais lenta. Para sua referência, eles foram executados na raiz de um sistema de arquivos bastante profundo ( docrootem uma instalação do Magento 2 Enterprise compreendendo 71.158 arquivos em 30.027 diretórios).

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


Esses dois também funcionam, mas dependem de comandos que não existem no Git Bash para 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


Se você quiser apenas o total do diretório atual, adicione -maxdepth 1 a find.


Observe que algumas das soluções sugeridas não retornam resultados precisos, então eu preferiria as soluções acima.

$ 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
thdoan
fonte
1
Em relação ao Git Bash para Windows, - no caso do Cygwin, dcfaz parte do bcpacote, então para obtê-dc lo é necessário instalar bc.
ruvim
1

Para Win32 DOS, você pode:

c:> dir / sc: \ diretório \ que você \ deseja

e a penúltima linha informará quantos bytes os arquivos ocupam.

Eu sei que isso lê todos os arquivos e diretórios, mas funciona mais rápido em algumas situações.

Sol
fonte
1

dué prático, mas findé útil no caso de você desejar calcular o tamanho de alguns arquivos apenas (por exemplo, usando filtro por extensão). Observe também que findeles próprios podem imprimir o tamanho de cada arquivo em bytes. Para calcular o tamanho total, podemos conectar o dccomando da seguinte maneira:

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

Aqui findgera sequência de comandos para dcgosto 123 + 456 + 11 +. Embora o programa completo deva ser0 123 + 456 + 11 + p (lembre-se da notação pós-fixada).

Portanto, para obter o programa completo, precisamos colocá-lo 0na pilha antes de executar a sequência de stdin e imprimir o número superior após a execução (o pcomando no final). Conseguimos isso por meio de dcopções:

  1. -e0é apenas um atalho para -e '0'colocar0 na pilha,
  2. -f- é para ler e executar comandos de stdin (aquele gerado por find aqui),
  3. -epé para imprimir o resultado ( -e 'p').

Para imprimir o tamanho em MiB, como 284.06 MiBpodemos usar -e '2 k 1024 / 1024 / n [ MiB] p'no ponto 3, em vez disso (a maioria dos espaços são opcionais).

ruvim
fonte
1

Isso pode ajudar:

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

O comando acima somará todos os arquivos deixando o tamanho dos diretórios.

Ataul Haque
fonte
1
Observe que esta solução é muito semelhante à resposta de Barun. Mas esta solução não soma arquivos em subdiretórios.
ruvim
1
@ruvim, ele não soma os arquivos ocultos também. Para somar os arquivos ocultos, a -Aopção deve ser adicionada a ls.
anton_rh
0

Usar:

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

Onde <DIR> é o diretório que você deseja inspecionar.

O '-c' fornece dados do total geral que são extraídos usando a parte 'total grep' do comando, e a contagem em Kbytes é extraída com o comando awk.

A única advertência aqui é se você tiver um subdiretório contendo o texto "total", ele também será cuspido.

Rob Jones
fonte