Tengo una carpeta con aproximadamente 20K archivos. Los archivos se nombran de acuerdo con el patrón xy_{\d1,5}_{\d4}\.abc
, por ejemplo xy_12345_1234.abc
. Quería comprimir los primeros 10K de ellos usando este comando:
ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz
sin embargo, el archivo resultante solo tenía unos 2K archivos dentro.
ls | sort -n -k1.4,1.9 | head -n10000 | wc -l
sin embargo, devuelve 10000, como se esperaba.
Me parece que estoy malentendido algo básico aquí ...
Estoy usando zsh 5.0.2 en Linux Mint 17.1, GNU tar 1.27.1
EDITAR:
bifurcación como lo sugiere @Archemar suena muy plausible, con la última bifurcación sobrescribiendo el archivo resultante: el archivo contiene la 'cola' de los archivos: 7773 a 9999 .
resultado de xargs --show-limit
:
Your environment variables take up 3973 bytes
POSIX upper limit on argument length (this system): 2091131
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2087158
Size of command buffer we are actually using: 131072
Reemplazar -c
con -r
o -u
no funcionó en mi caso. El mensaje de error fuetar: Cannot update compressed archives
usando ambos -r
y -u
es inválido y falla contar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option
sustituyendo -c
con -a
parece ser válido también y no con el mismo tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
, aunque yo no reconozco el tema azf
y Acdtrux
parece disjunta a mí.
EDITAR 2:
-T parece una buena manera, también he encontrado un ejemplo aquí .
Sin embargo cuando lo intento
ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T -
yo obtengo
tar: option requires an argument -- 'T'
bueno, tal vez los nombres de los archivos no llegan al alquitrán? Pero parece que lo hacen porque cuando ejecuto
ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T -
yo obtengo
tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab
Cannot stat: File name too long
Entonces, ¿por qué tar no ve los nombres de los archivos?
ls
find
, que tiene la-print0
opción de usar un byte nulo como delimitador en lugar de una nueva línea.sort
puede manejar eso con la-z
bandera.head
, desafortunadamente no maneja los delimitadores de bytes nulos, pero esta respuesta tiene una solución que se usatr
para intercambiar\n
y\0
antes y despuéshead
.tar
tiene--null -T -
que leer nombres de archivo delimitados por nulosstdin
.Respuestas:
has alcanzado el límite de xargs?
tratar :
.tgz
archivo ficticiotar czf xy_0_10000.tar.gz /hello/world
-czf
por-Azf
cuando xarg llegue a su límite, bifurcará el comando, por lo que el comando que finalmente ejecutó fue
Como cada alquitrán anula el anterior, solo debería obtener la última
tar c
ejecución.Editar:
1) de
acuerdo conanexar lo realiza (cualquiera)man tar
en unbuntu,-a
y -r parece equivalente,-A, --catenate, --concatenate
2)
zip
(nogzip
) se puede usar para agregar un archivo, tal vez una opción gzip sea suficiente. (uso| xargs zip -qr xy_0_0000.zip
, esto dará como resultado un archivo zip, no un .tar.gz)3) para usar la solución de @ rsanchez
Es importante agregar la opción al alquitrán de manera adecuada, intente
where:
-T -
opción de uso medio-T
y uso-
como argumento para-T
(podría haber generado una lista de archivos/tmp/foo.lst
y luego usar-T /tmp/foo.lst
)fuente
a (add)
para agregar los archivos en el archivo tar. Luego, puede abrir el tar y eliminar la carpeta (usando 7zip o algo así)touch xy_0_10000.tar.gz && { _the full command here_ ; }
.gz
archivo no válido .-r
agregado pero-a
autocomprimido, lo cual no es equivalente. Y-rz
no funciona:zip
puede agregarse a un archivo existente porque el directorio no está comprimido, perotar
con compresión comprime los metatdatos junto con los datos. Puedetar -r
trocear en un archivo sin comprimir y luego comprimir el resultado. O ...No hay necesidad de eso
xargs
. Si le datar
la-T -
opción directamente , leerá los nombres de archivo de la entrada estándar.Por ejemplo:
fuente
...| tar Tczf xy_...
,...| tar Tcz -f xy_...
...| tar -czf xy_... -T
y varias otras permutaciones, pero solo estoy obteniendotar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
,tar: -f: Cannot stat: No such file or directory
si se usa por-f
separado de otras opciones ytar: option requires an argument -- 'T'
. ¿Podría agregar un ejemplo de uso?-T -
al final de latar
lista de opciones no funcionó, pero su ejemplo sí. Desafortunadamente, mi pregunta en realidad tenía dos partes: la fuente del error y una posible mejora. Mientras superaste a este último, Archemar se destacó en el primero y casi tenía el último derecho. No estoy seguro de cuál de sus respuestas aceptar ya que obviamente ambas fueron útiles.Quiero complementar las otras dos respuestas con una solución zsh , que no analiza ls ni necesita xargs . Sin embargo, no estoy seguro en este momento, si también sufre la limitación de la longitud de la línea de comando.
Defina una función que genere su clave de clasificación deseada modificando
$REPLY
.Esto es equivalente a tu
sort -n -k1.4,1.9
Genere una matriz
$files
con los nombres de archivo ordenados con la función anterior:Esto es equivalente a
ls | sort -n -k1.4,1.9
Devuelva los primeros 10 000 archivos con
Esto es equivalente a
ls | sort -n -k1.4,1.9 | head -n10000
Entonces, en general, esto debería hacer el truco:
fuente