Suponha que exista um diretório de armazenamento de imagens ./photos/john_doe
, no qual existem vários subdiretórios, nos quais residem muitos arquivos (digamos *.jpg
). Como posso calcular um tamanho de resumo desses arquivos abaixo da john_doe
ramificação?
Eu tentei du -hs ./photos/john_doe/*/*.jpg
, mas isso mostra apenas arquivos individuais. Além disso, isso rastreia apenas o primeiro nível de aninhamento do john_doe
diretório, como john_doe/june/
, mas pula john_doe/june/outrageous/
.
Então, como eu poderia percorrer todo o ramo, resumindo o tamanho de certos arquivos?
files
directory
directory-structure
size
mbaitoff
fonte
fonte
LC_ALL=POSIX
como prefixo para sempre grep para total como este:LC_ALL=POSIX find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
-name
, altere o grep paragrep -P "\ttotal$"
senão ele captura todos os arquivos que terminam com "total" também.bc
, por isso aqui é uma solução mais portátil:find -name '*.jpg' -type f -exec du -bc {} + | grep total$ | cut -f1 | awk '{ total += $1 }; END { print total }'
fornece o uso total dos meus
.jpg
arquivos neste diretório.Para lidar com vários diretórios, você provavelmente teria que combinar isso de
find
alguma forma.Você pode achar exemplos de comandos du úteis (também inclui
find
)fonte
-R
opção em man7.org/linux/man-pages/man1/du.1.html . E eu não acho que uma opção recursiva ajudaria nesse caso, porque o shell está fazendo a expansão global antes de passar os argumentos paradu
.Primeiramente, você precisa de duas coisas:
-c
opção dedu
, dizer para produzir um total geral;**
( instruções de activação ) oufind
( exemplo ) ou a atravessam subdirectórios.fonte
find
pode retornar resultados incorretos.du -ch -- ./{dir1,dir2}/*.jpg
oudu -ch -- ./{prefix1*,prefix2*}.jpg
Argument list too long
erro ao processar cerca de 300k arquivos de texto.getconf ARG_MAX
. Se você tiver mais, precisará processar os arquivos um por um ou em lotes com um loop for.A resposta final é:
e versão ainda mais rápida, não limitada pela RAM, mas que requer o GNU AWK com suporte a bignum:
Esta versão possui os seguintes recursos:
find
para especificar os arquivos que você está procurandofind
faz uma correspondência curinga simples de nomes de arquivos5.5K
,176.7M
, ...)| numfmt --to=si
fonte
As respostas dadas até agora não levam em consideração que a lista de arquivos passada de find para du pode ser tão longa que a find divide automaticamente a lista em partes, resultando em várias ocorrências de
total
.Você pode
grep total
(localidade!) E resumir manualmente, ou usar um comando diferente. No AFAIK, existem apenas duas maneiras de obter um total geral (em kilobytes) de todos os arquivos encontrados pela localização:find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'
Explicação
find . -type f -iname '*.jpg' -print0
: Encontre todos os arquivos com a extensão jpg, independentemente do caso (por exemplo, * .jpg, * .JPG, * .Jpg ...) e os produza (terminação nula).xargs -r0 du -a
: -r: Xargs chamaria o comando mesmo sem argumentos passados, o que -r impede. -0 significa cadeias terminadas em nulo (não nova linha finalizada).awk '{sum+=$1} END {print sum}'
: Resuma os tamanhos de arquivo gerados pelo comando anteriorE, para referência, o outro caminho seria
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-
fonte
du --file0-from
demorou mais tempo porque você o executou primeiro (efeito de cache).xargs
, váriosdu -a
podem ser executados, portanto, você pode ter discrepâncias se houver links físicos.Se a lista de arquivos for muito grande e não puder ser passada para uma única chamada de
du -c
, em um sistema GNU, você poderá:(tamanho expresso em número de blocos de 512 bytes). Como
du
se tentasse contar links físicos apenas uma vez. Se você não se importa com links físicos, pode simplificá-lo para:Se você deseja o tamanho em vez do uso do disco, substitua
%b
por%s
. O tamanho será então expresso em bytes.fonte
-bash: bc: command not found
Centos - Linux 2.6.32-431.el6.x86_64bc
é um comando POSIX não opcional.As soluções mencionadas até o momento são ineficientes (o custo do executivo) e exigem trabalho manual adicional para somar se a lista de arquivos é longa ou não funciona no Mac OS X. A solução a seguir é muito rápida, deve funcionar em qualquer sistema e gera a resposta total em GB (remova a / 1024 se desejar ver o total em MB):
find . -iname "*.jpg" -ls |perl -lane '$t += $F[6]; print $t/1024/1024/1024 . " GB"'
fonte
-iname
nem-ls
são padrão / portátil, por isso não vai funcionar em qualquer sistema também. Também não funcionará corretamente se houver nomes de arquivos ou destinos de link simbólico que contenham caracteres de nova linha.Melhorando a ótima resposta do SHW para fazê-lo funcionar com qualquer localidade, como Zbyszek já apontou em seu comentário:
fonte
du naturalmente percorre a hierarquia de diretórios e o awk pode executar a filtragem, portanto algo como isto pode ser suficiente:
Isso funciona sem o GNU.
fonte
stat
chamada para arquivos que não correspondem ao padrão pesquisado.