Obtenga el tamaño total de los archivos de un archivo que contiene una lista de archivos

14

Tengo un archivo que contiene una lista de archivos que me gustaría saber el tamaño total de los archivos. ¿Hay un comando para hacerlo?

Mi sistema operativo es un Linux muy básico (Qnap TS-410).

EDITAR:

Algunas líneas del archivo:

/ share / archive / Bailey Test / BD006 / 0.tga
/ share / archive / Bailey / BD007 / 1 versión 1.tga
/ share / archive / Bailey 2 / BD007 / example.tga

Nicolas
fuente
Danos algunas líneas de ejemplo del archivo.
EEAA
Ejemplo del archivo agregado.
Nicolas
Eso es algún tipo de NAS, ¿verdad? ¿Tienes busybox instalado?
cjc
Sí, y creo que ya está instalado, ¿por qué?
Nicolas

Respuestas:

13

Creo que algo como esto funcionaría en busybox:

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

No tengo el mismo entorno que tú, pero si encuentras problemas con espacios en los nombres de archivo, algo como esto también funcionaría:

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

Edición 1 :
@stew está justo en su publicación a continuación, du muestra el uso del disco y no el tamaño exacto del archivo. Para cambiar el comportamiento, busybox usa el indicador -a, así que intente: du -a "$file"para un tamaño de archivo exacto y compare la salida / comportamiento.

Mattias Ahnberg
fuente
1
Gracias por su aporte, el primer comando regresa /usr/bin/du: Argument list too long(casi 80,000 líneas en mi archivo). ¿Su segundo comando me da un aviso una vez que presiono enter, esperando algo más?
Nicolas
Difícil de decir con su entorno. ¿Es el símbolo del sistema normal o simplemente un indicador parpadeante? Si es lo último, puede que sea lento esperando el resultado, si es un "mensaje de entrada", ¿podría ser que te perdiste algún carácter? Y si es un mensaje normal, no lo sé, lo probé completamente antes de escribirlo. :(
Mattias Ahnberg
es un "indicador de entrada" cuando hago lo siguiente cat tgafiles.txt | while read file;do du "$file" done | awk '{i+=$1} END {print i}'. gracias mattias
Nicolas
1
Ah! Si pones todo en una línea necesitas otra; así: cat tgafiles.txt | while read file;do du "$file";done | awk '{i+=$1} END {print i}'(es decir, antes de hacerlo).
Mattias Ahnberg
¡Correcto! Funcionó perfectamente, ¡salud! (aunque podría haber descubierto este error por mí mismo)
Nicolas
8
du -c `cat filelist.txt` | tail -1 | cut -f 1

-cagrega línea "tamaño total";
tail -1toma la última línea (con tamaño total);
cut -f 1corta la palabra "total".

olegzhermal
fuente
Esto falla con du - argumento de la lista demasiado larga. Mi lista de archivos es grande. La siguiente respuesta con xargs parece ser la solución más fácil.
Syclone0044
4

No sé si sus herramientas de Linux son capaces de esto, pero:

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

Haga, los xargs establecerán el delimitador para que sea un personaje de nueva línea, y du producirá un gran total para usted.

Al mirar http://busybox.net/downloads/BusyBox.html parece que "busybox du" admitirá la opción de total general, pero los "busybox xargs" no admitirán delimitadores personalizados.

De nuevo, no estoy seguro de su conjunto de herramientas.

cjc
fuente
aquí está el resultado:xargs: invalid option -- d
Nicolas
Impresionante: trabajar con el busybox linux de un NAS es como un episodio de McGuyver, tratando de construir un avión que funcione con algunos lienzos, palos y cordeles.
cjc
Qué tal esto, si tiene espacio para ello en una máquina diferente: copie todos los archivos que le interesan en otro linux completamente funcional y luego ejecute la solución de Stew allí. Hacer eso podría ser mucho más fácil que tratar de descubrir si busybox es capaz de hacer este tipo de cosas.
CJC
1
Creo que la respuesta es la mejor. Es conciso y es mucho más rápido que las otras respuestas en este hilo.
zymhan
Buena respuesta. Es posible que desee dejar de lado -cya que xargs hará varias llamadas dusi la lista de archivos es lo suficientemente larga, produciendo varios dutotales.
qwr
4
while read filename ;  do stat -c '%s' $filename ; done < filelist.txt | awk '{total+=$1} END {print total}'

Esto es similar a la solución de Mattias Ahnberg. El uso de "leer" evita problemas con nombres de archivo / directorios con espacios. Yo uso en statlugar de duobtener el tamaño del archivo. du está obteniendo la cantidad de espacio que está utilizando en el disco en lugar del tamaño del archivo, que podría ser diferente. Dependiendo de su sistema de archivos, un archivo de 1 byte seguirá ocupando 4k en el disco (o lo que sea el tamaño de bloque). Entonces, para un archivo de 1 byte, stat dice 1 byte y du dice 4k.

estofado
fuente
Buen comentario sobre filesize vs disksize!
Mattias Ahnberg
Comentario muy interesante, desafortunadamente mi Linux no conoce el statcomando:stat: command not found
Nicolas
Es posible que tengas que decir "busybox stat".
cjc
dice stat: applet not founden este caso
Nicolas
4

Aquí hay otra solución al problema:

cat filelist.txt | tr '\n' '\0' | wc -c --files0-from=-
dsamarin
fuente
Para mí (en Cygwin) du -bccorre mucho más rápido.
qwr
2

Intenta algo como esto:

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

Para tratar adecuadamente con espacios en caminos:

$ find /path/to/files -type f -print0 | xargs -0 ls -l | awk '{x+=$5} END {print "total bytes: " x}' 
EEAA
fuente
gracias por su aporte, desafortunadamente creo que hay un problema con los espacios en los directorios dentro de mi archivo que no se escapan con un "\"., por lo tanto, se rompe al pasar por la lista de archivos.
Nicolas
¿Puede omitir la lista de archivos de texto y simplemente generar esto fuera de la salida de find?
EEAA
desafortunadamente la lista es demasiado larga, hay 79159 líneas de archivos (ruta completa), es por eso que la envío a un archivo; ¿Tal vez pueda agregar un argumento acerca de escapar del resultado del hallazgo?
Nicolas
no hay argumento "-print0" con el hallazgo en mi sistema Linux
Nicolas
@Nicolas: eso se debe al uso de busybox despojado en findlugar del findbinario real .
EEAA
1

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

Pradeep
fuente