Tamanho de todos os arquivos de uma certa extensão em uma árvore de diretórios

10

Eu quero saber o tamanho do arquivo com extensão .o (arquivo de objeto) na minha pasta pessoal.

Eu posso encontrar todos os arquivos objeto usando

find . -name '*.o'

Como posso calcular o tamanho total desses arquivos?

    
por alhelal 26.08.2016 / 11:25

3 respostas

18

Você está procurando por pipes ( | ). Eles são uma maneira de conectar vários comandos e passar a saída de um comando como entrada para outro. Nesse caso, você deseja passar todos os nomes de arquivo que encontrar como entrada para du (que calcula o tamanho). No entanto, porque du espera nomes de arquivos e os resultados de find são apenas uma lista de texto (sim, o texto consiste em nomes de arquivos, mas du não sabe disso, tudo o que vê é texto), você precisa usar algo como xargs , o que ocupará cada linha de texto, tratá-la como um nome de arquivo e passá-la para du . Colocando tudo isso junto, conseguimos:

find . -name "*.o" | xargs du -sch
  • você deve sempre citar os padrões que você dá a find (como eu fiz acima: "*.o" ). Se você não fizer isso, o shell expandirá o *.o para os nomes de quaisquer arquivos correspondentes no diretório atual. Funcionou neste caso apenas porque você não tinha arquivos correspondentes.

  • Os sinalizadores -sch para du estão documentados em man du :

    -c, --total
          produce a grand total
    -h, --human-readable
          print sizes in human readable format (e.g., 1K 234M 2G)
    -s, --summarize
          display only a total for each argument
    

Observe, no entanto, que isso falhará nos nomes de arquivos que contêm espaço em branco. Isso certamente não será um problema para arquivos de objetos, mas, no futuro, se você também precisar lidar com espaços, use:

find . -name "*.o" -print0 | xargs -0 du -sch

A -print0 faz find imprimir linhas separadas por NULL e a -0 faz xargs tomar essas linhas como entrada.

Como alternativa, você pode ter find imprimir os tamanhos em si e, em seguida, somar:

find . -name "*.o" -printf '%s\n' | awk '{c+=}END{print c}'

Isso também contorna o problema mencionado por @Serg em os comentários onde há muitos argumentos e o comando é dividido em comandos separados.

Se você estiver usando bash (provavelmente você é), há uma maneira mais simples:

shopt globstar 
du -sch **/*.o

O comando shopt globstar faz com que ** correspondam a todos os arquivos e / ou mais subdiretórios. Depois de ativá-lo, **/*.o corresponderá a todos os arquivos (e diretórios) cujos nomes terminam em .o , para que possamos passar isso diretamente para du .

Observe que, diferentemente da abordagem find , isso não corresponderá aos arquivos ocultos (aqueles cujo nome começa com . ). Para combinar com isso também, faça:

shopt -s dotglob globstar
du -sch **/*.o
    
por terdon 26.08.2016 / 11:47
8

Use -exec flag para executar o comando du com ; (o que significa cada arquivo)

find . -name "*.o" -exec du -b {} \; | awk '{total+=}END{print total}' 

Exemplo de saída:

$ find . -name "*.txt"  -exec du -b {} \; | awk '{total+=}END{print total,"bytes" }'                                     
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes

find é recursivo - o que significa que ele percorre todos os subdiretórios. Se você quiser obter o total de todos os arquivos *.o no diretório atual, faça

du -b -c *.o
    
por Sergiy Kolodyazhnyy 26.08.2016 / 11:45
0

com perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

Tamanho de todos os arquivos PDF não ocultos no diretório atual.

    
por Marwen Bkh 26.08.2016 / 11:46