Tenho uma estrutura de pastas grande e preciso obter o tamanho de um determinado subconjunto. Os diretórios que preciso contar são definidos por terem subdiretórios especÃficos:
find . \( -iname a -or ... \) -printf "\"%h\"\n" | xargs -- du -sch | sort -rh
Isso funciona bem até certo ponto. Mas quando há muitas pastas, obtenho vários totais no resultado (usar echo
em vez de du
with xargs
mostra que a saÃda está dividida em várias linhas, ou seja, chamadas para du
).
Isto provavelmente é causado por alguns limites de buffer. Existe alguma maneira de contornar isso, para que eu obtenha apenas um único tamanho total na saÃda?
Sua citação não faz sentido, a saÃda
find
não é interpretada por um shell; nem usar\n
como separador; você deve sempre usar\0
zero byte como separador e usarxargs
with-0
; o byte zero nunca pode fazer parte de um nome ou caminho de arquivo!De qualquer forma, isso pode não resolver o problema em questão:
As linhas de comando têm um comprimento máximo; portanto, ter uma única chamada
du
com muitos parâmetros pode ser simplesmente impossÃvel.Se você possui GNU coreutils
du
(provavelmente possui se estiver em um Linux completo,du --version
diria), você pode usardu --files0-from=
para ler os arquivos de um arquivo, ou especificamente, da entrada padrão, ao usar-
como nome de arquivo:Stéphane ressalta que faria mais sentido remover as duplicatas dos arquivos antes de serem processados:
LC_ALL=C
instrui o sort a usar o "locale padrão inglês-UNIX" para classificação. Geralmente é uma boa ideia evitar ordens diferentes dependendo do idioma do usuário.Eu resolveria no TXR Lisp assim. Digamos que os diretórios que queremos encontrar sejam caracterizados por terem subdiretórios chamados
alpha
e :beta
gamma
Como estamos usando a
**
expansão de estrela dupla e chave, devemos usar aglob*
função; aglob
função é um wrapper quase direto para a função da biblioteca POSIX C de mesmo nome;glob*
implementa os recursos adicionais além disso.A barra final em nosso padrão glob garante que apenas os diretórios sejam correspondidos; um arquivo ou outro objeto nomeado
gamma
não conta.Depois de identificarmos os diretórios correspondentes, iteramos sobre seus pais (com a ajuda de
dir-name
) e processamos recursivamente cada um deles usandoftw
, somando os tamanhos dos objetos visitados multiplicando sua contagem total de blocos por 512.Para contar inodes duplicados (links fÃsicos para o mesmo arquivo) apenas uma vez:
Isto é necessário não apenas se houver links fÃsicos, mas possivelmente se o mesmo diretório aparecer mais de uma vez. Suponha que temos
path/to/gamma
epath/to/beta
. O pai deles é o mesmo diretório; acabamos processando duas vezes. O código poderia ser melhorado para evitar isso, mas o hash do inode evitará pelo menos a contagem dupla.