Obter o tamanho total dos arquivos de um arquivo que contém uma lista de arquivos


14

Eu tenho um arquivo contendo uma lista de arquivos que gostaria de saber o tamanho total dos arquivos. Existe um comando para fazer isso?

Meu sistema operacional é um linux muito básico (Qnap TS-410).

EDITAR:

Algumas linhas do arquivo:

/ share / archive / Teste Bailey / BD006 / 0.tga
/ share / archive / Bailey / BD007 / 1 versão 1.tga
/ share / archive / Bailey 2 / BD007 / example.tga


Dê-nos alguns exemplos de linhas do arquivo.
EEAA

Exemplo do arquivo adicionado.
Nicolas

Isso é algum tipo de NAS, certo? Você tem o busybox instalado?
CJC

Sim, é e acho que já está instalado, por quê?
Nicolas

Respostas:


13

Acredito que algo assim funcionaria no busybox:

du `cat filelist.txt` | awk '{i+=$1} END {print i}'

Eu não tenho o mesmo ambiente que você, mas se você encontrar problemas com espaços nos nomes de arquivos, algo como isso também funcionaria:

cat filelist.txt | while read file;do
  du "$file"
done | awk '{i+=$1} END {print i}'

Edit 1 :
@stew está certo em seu post abaixo, du mostra o uso do disco e não o tamanho exato do arquivo. Para alterar o comportamento, o busybox usa o sinalizador -a, então tente: du -a "$file"para o tamanho exato do arquivo e compare a saída / comportamento.


1
Obrigado pela sua entrada, o primeiro comando retorna /usr/bin/du: Argument list too long(quase 80.000 linhas no meu arquivo). Seu segundo comando só me dá um prompt assim que eu pressiono enter, esperando por algo mais?
Nicolas

Difícil dizer com seu ambiente. É o prompt de comando normal ou apenas um prompt piscando? Se for o último, pode ser lento aguardando pelo resultado, se for um "prompt de entrada", pode ser que você tenha perdido algum caractere? E se é um prompt normal, não sei, testei bastante antes de digitá-lo. :(
Mattias Ahnberg

é um "prompt de entrada" quando faço o seguinte cat tgafiles.txt | while read file;do du "$file" done | awk '{i+=$1} END {print i}'. obrigado mattias
Nicolas

1
Ah! Se você colocar tudo em uma linha, precisará de outra; assim: cat tgafiles.txt | while read file;do du "$file";done | awk '{i+=$1} END {print i}'(ou seja, antes de terminar).
Mattias Ahnberg

Spot on! Funcionou perfeitamente, felicidades! (embora eu poderia ter descoberto esse erro por mim)
Nicolas

8
du -c `cat filelist.txt` | tail -1 | cut -f 1

-cadiciona a linha "tamanho total";
tail -1pega a última linha (com tamanho total);
cut -f 1corta a palavra "total".


Isso falha com a lista de du-argumentos muito longa. Minha lista de arquivos é grande. A resposta abaixo com xargs parece ser a solução mais fácil.
Syclone0044

4

Não sei se suas ferramentas Linux são capazes disso, mas:

cat /tmp/filelist.txt  |xargs -d \\n du -c

Sim, o xargs definirá o delimitador como um caractere de nova linha e du produzirá um total geral para você.

Olhando http://busybox.net/downloads/BusyBox.html , parece que o "busybox du" suportará a opção total geral, mas o "busybox xargs" não suportará delimitadores personalizados.

Novamente, não tenho certeza do seu conjunto de ferramentas.


aqui está o resultado:xargs: invalid option -- d
Nicolas

Impressionante: trabalhar com o busybox linux de um NAS é como um episódio de McGuyver, tentando construir um avião de trabalho a partir de telas, paus e barbantes.
CJC

Que tal isso, se você tiver espaço para isso em uma máquina diferente: copie todos os arquivos de seu interesse para outro linux totalmente funcional e execute a solução da Stew lá. Fazer isso pode ser muito mais fácil do que tentar descobrir se o busybox é capaz desse tipo de coisa.
CJC

1
Eu acho que a resposta é a melhor. É conciso e é muito mais rápido do que as outras respostas neste tópico.
Zymhan

Boa resposta. Você pode deixar de fora, -cpois o xargs fará várias chamadas paradu se a lista de arquivos for longa o suficiente, produzindo vários dutotais.
Qd

4
while read filename ;  do stat -c '%s' $filename ; done < filelist.txt | awk '{total+=$1} END {print total}'

Isso é semelhante à solução de Mattias Ahnberg. O uso de "read" contorna problemas com nomes de arquivos / diretórios com espaços. Eu uso em statvez de duobter o tamanho do arquivo. du está obtendo a quantidade de espaço que está usando no disco, em vez do tamanho do arquivo, que pode ser diferente. Dependendo do seu sistema de arquivos, um arquivo de 1 byte ainda ocupará 4k no disco (ou qualquer que seja o tamanho do bloco). Portanto, para um arquivo de 1 byte, stat diz 1 byte e du diz 4k.


Bom comentário sobre o tamanho do arquivo x tamanho do disco!
Mattias Ahnberg 19/01/12

Comentário muito interessante, de fato, infelizmente meu linux não conhece o statcomando:stat: command not found
Nicolas

Você pode ter que dizer "status da caixa ocupada".
CJC

diz stat: applet not foundneste caso
Nicolas

4

Aqui está outra solução para o problema:

cat filelist.txt | tr '\n' '\0' | wc -c --files0-from=-

Para mim (no cygwin) du -bccorre muito mais rápido.
Q26

2

Tente algo como isto:

$ cat filelist.txt | xargs ls -l | awk '{x+=$5} END {print "total bytes: " x}' 

Para lidar adequadamente com espaços nos caminhos:

$ find /path/to/files -type f -print0 | xargs -0 ls -l | awk '{x+=$5} END {print "total bytes: " x}' 

obrigado pela sua contribuição, infelizmente, acho que há um problema com os espaços nos diretórios dentro do meu arquivo não serem escapados com um "\"., portanto, ele quebra ao percorrer a lista de arquivos.
Nicolas

Você pode ignorar a lista de arquivos de texto e apenas gerar isso fora da saída de find?
EEAA

infelizmente, a lista é muito longa; existem 79159 linhas de arquivos (caminho completo); é por isso que a produzo em um arquivo; talvez eu possa adicionar um argumento sobre como escapar do resultado da descoberta?
Nicolas

não há nenhum argumento "-print0" com a descoberta no meu sistema linux
Nicolas

@ Nicolas - isso se deve ao fato de usar o busybox despojado em findvez do findbinário real .
EEAA

1

cat docs.txt | xargs -d \\n du -sk | awk '{total+=$1} END{print total}'

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.