Lea los archivos .gz dentro de los archivos .tar sin extraer
Tengo un archivo .tar que contiene muchos archivos .gz dentro de una carpeta. Cada uno de estos archivos gz contiene un archivo .txt. Otras preguntas de Stackoverflow relacionadas con este problema se dirigen a extraer los archivos.
Estoy tratando de leer de forma iterativa el contenido de cada archivo .txt sin extraerlos, porque el .tar es grande.
Primero leo el contenido del archivo .tar:
import tarfile
tar = tarfile.open("FILE.tar")
tar.getmembers()
O en Unix:
tar xvf file.tar -O
Luego intenté usar el método extractfile de tarfile, pero obtengo un error: “módulo ‘tarfile’ no tiene el atributo ‘extractfile'”. Además, ni siquiera estoy seguro de que sea el método correcto.
import gzip
for member in tar.getmembers():
m = tarfile.extractfile(member)
file_contents = gzip.GzipFile(fileobj=m).read()
Si desea crear un archivo de ejemplo para simular el archivo original:
$ mkdir directory
$ touch directory/file1.txt.gz directory/file2.txt.gz directory/file3.txt.gz
$ tar -c -f file.tar directory
Esta es la versión final que me funcionó después de usar la sugerencia de Mark Adler:
import tarfile
tar = tarfile.open("file.tar")
members = tar.getmembers()
# Aquí agrego los resultados en una lista, porque no pude
# analizar el tipo de archivo devuelto por .getmembers():
tar_name = []
for elem in members:
tar_name.append(elem.name)
# Luego cambié tarfile.extractfile a tar.extractfile como sugirió:
for member in tar_name:
# Estoy usando esto porque tengo otros archivos que no son gzs en el directorio
if member.endswith(".gz"):
m = tar.extractfile(member)
file_contents = gzip.GzipFile(fileobj=m).read()
davy.ai
El código y el comando Unix proporcionados son formas correctas de acceder al contenido de un archivo .tar con archivos .gz dentro. Sin embargo, el mensaje de error “el módulo ‘tarfile’ no tiene el atributo ‘extractfile'” es correcto; no hay un método ‘extractfile’ en el módulo tarfile. En su lugar, puedes usar el método ‘extractfile’ en el propio objeto TarFile, de esta manera:
Ten en cuenta que usamos el método ‘isreg()’ para verificar que el archivo sea un archivo regular, en lugar de un directorio o enlace, antes de intentar extraer su contenido.