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

Nicolas
fonte
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.

Mattias Ahnberg
fonte
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".

olegzérmico
fonte
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.

cjc
fonte
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.

ensopado
fonte
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=-
dsamarin
fonte
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}' 
EEAA
fonte
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}'

Pradeep
fonte