Eliminar archivos del archivo tar

17

Tengo un archivo grande foo.tar.xzque contiene muchos archivos (por ejemplo, 200000). Descubrí que este archivo contiene algunos (alrededor de 5000) archivos que no quiero. No tengo suficiente espacio en disco para descomprimir todo en mi disco; Además, me temo que los atributos / derechos podrían perderse si lo hago. Sin embargo, tengo suficiente espacio para alojar dos copias del archivo comprimido . ¿Existe una herramienta para eliminar algunos de los archivos del archivo (especificado con una expresión regular en el nombre del archivo) sobre la marcha, es decir, sin descomprimir el archivo en archivos individuales?

FUZxxl
fuente

Respuestas:

15

GNU tar tiene una --deleteopción que también funciona con archivos hoy en día.

Úselo así, por ejemplo:

tar -vf yourArchive.tar --delete your/path/to/delete

Cuidado: lo más probable es que no funcione en ningún tipo de medio de cinta magnética. Pero tarno tiene problemas para trabajar en una tubería, por lo que puede usar un archivo tar temporal y sobrescribir la cinta con eso después. Tampoco funcionará en archivos comprimidos, por lo que deberá descomprimir el archivo.

Además, la operación será bastante lenta en cualquier caso, debido a la naturaleza lineal empaquetada (por diseño) de los archivos tar.

Evi1M4chine
fuente
1
Existe, pero no funciona con archivos donde no es posible el acceso aleatorio (por ejemplo, comprimir archivos), pero este es mi caso de uso.
FUZxxl
1
El otro problema es que no puedo especificar un patrón para eliminar. Tenga en cuenta mi comentario de 2013, donde ya abordo las deficiencias de gtar --delete.
FUZxxl
44
@FUZxxl -Tfunciona --deletey le --wildcardspermite usar patrones en lugar de nombres de archivo, por lo tanto, cree un archivo temporal que contenga los patrones y use unxz < file.tar.xz | tar --wildcards --delete -T patternfile | xz > file2.tar.xz. No hará una expresión regular completa (si lo necesita, solo use tar -ty cree una lista de nombres de archivo para eliminar), solo patrones de coincidencia de nombre de archivo.
Random832
14

(editado, ya que entendí mal la pregunta, que también fue editada)

Lo mejor que puede hacer es extraer, eliminar y volver a comprimir todo el archivo.

unxz < foobar-old.tar.xz | tar --delete foo/bar | xz > foobar-new.tar.xz

No es posible eliminar archivos de un alquitrán directamente.

tar es un flujo, originalmente diseñado para unidades de cinta que no hacen búsquedas aleatorias, mientras que en teoría podría ser posible en un sistema de archivos de disco hacer un agujero / reescribir el archivo restante, con compresión, el punto es discutible como la mayoría, si no todos Los métodos de compresión dependen en gran medida de los contenidos que ocurrieron anteriormente en el archivo. Para hacer esto en su lugar, necesitará un conocimiento muy detallado sobre el método de compresión y el formato del archivo tar. Eso es complejidad hasta el punto de que nadie se molestaría con eso. Es más barato mantener los archivos e ignorarlos.

Si necesita esta funcionalidad, es probable que tar no sea lo que desea.

Frostschutz
fuente
Esos archivos representan el 35% del tamaño de los archivos. Las restricciones que señala aparentemente solo se aplican si reescribo el archivo, no si lo modifico fuera de lugar, lo que puedo hacer (tengo suficiente espacio para guardar el archivo empaquetado dos veces). ¿Existe tal herramienta?
FUZxxl
Puede que haya entendido mal su pregunta entonces. Si ESTÁ dispuesto a desempaquetar el alquitrán después de todo y volver a empaquetarlo (solo sin crear realmente los archivos alquitranados, es decir, un alquitrán directo a una tubería de alquitrán), puede ser posible.
frostschutz
Sí, puedo hacer eso. Es solo que los archivos tienen uids / gids / atributos que necesito preservar. Además, no tengo suficiente espacio en disco para guardar la representación desempaquetada. Sin embargo, tengo suficiente espacio para guardar dos archivos empaquetados.
FUZxxl
1
Eso no es problema en absoluto. Si puedo hacer esto de una sola vez, el tiempo no será demasiado largo. No puedo imaginar ningún formato de archivo que permita una eliminación rápida mientras se libera el almacenamiento.
FUZxxl
1
--wildcardsayuda ... Tuve que incluir ./al comienzo del patrón sin embargo ...
Gert van den Berg
-4

De acuerdo con el manual , puede pasar una lista de nombres de archivo tara solo extraerlos. Por ejemplo:

$ tar --file archive.tar --list
foo
bar
baz

$ tar --file archive.tar --extract foo
Don Juan de Python
fuente
No veo cómo --extract me ayuda. ¿Podrías dar más detalles? Tenga en cuenta que no puedo descomprimir el archivo (o partes sustanciales) en el disco.
FUZxxl
2
Por favor, no solo publique enlaces: esta es una wiki; agregue suficiente contenido para que sea innecesario que la gente salga de la página para comprender su respuesta.
jasonwryan