leer el contenido del archivo tar sin deshacerlo, en un script de Python

82

Tengo un archivo tar que tiene varios archivos dentro. Necesito escribir un script de Python que lea el contenido de los archivos y proporcione el recuento de caracteres totales, incluido el número total de letras, espacios, caracteres de nueva línea, todo, sin deshacer el archivo tar.

randeepsp
fuente
¿Cómo se pueden contar los caracteres / letras / espacios / todo sin extraerlos a otro lugar?
USTED
16
esa es precisamente la pregunta que se hace.
Erik Kaplun

Respuestas:

127

puedes usar getmembers()

>>> import  tarfile
>>> tar = tarfile.open("test.tar")
>>> tar.getmembers()

Después de eso, puede usar extractfile()para extraer los miembros como objeto de archivo. Solo un ejemplo

import tarfile,os
import sys
os.chdir("/tmp/foo")
tar = tarfile.open("test.tar")
for member in tar.getmembers():
    f=tar.extractfile(member)
    content=f.read()
    print "%s has %d newlines" %(member, content.count("\n"))
    print "%s has %d spaces" % (member,content.count(" "))
    print "%s has %d characters" % (member, len(content))
    sys.exit()
tar.close()

Con el objeto de archivo fen el ejemplo anterior, puede usar read(), readlines()etc.

ghostdog74
fuente
17
"for member in tar.getmembers ()" se puede cambiar a "for member in tar", que es un generador o un iterador (no estoy seguro de cuál). Pero recibe un miembro de uno en uno.
huggie
2
Acabo de tener un problema similar, pero el módulo tarfile parece comerse mi ram, aunque usé la 'r|'opción.
devsnd
2
¡Ah! Lo resolví. Suponiendo que escribirías el código como lo sugiere huggie, tienes que "limpiar" la lista de miembros de vez en cuando. Entonces, dado el ejemplo de código anterior, eso sería tar.members = []. Más información aquí: bit.ly/JKXrg6
devsnd
será tar.getmembers()llamado varias veces cuando lo ponga en un for member in tar.getmembers()bucle?
Haifeng Zhang
1
Después de hacer "f = tar.extractfile (member)", ¿también necesita cerrar f?
bolei
12

necesita utilizar el módulo tarfile. Específicamente, usa una instancia de la clase TarFile para acceder al archivo y luego accede a los nombres con TarFile.getnames ()

 |  getnames(self)
 |      Return the members of the archive as a list of their names. It has
 |      the same order as the list returned by getmembers().

Si, en cambio, desea leer el contenido , utilice este método

 |  extractfile(self, member)
 |      Extract a member from the archive as a file object. `member' may be
 |      a filename or a TarInfo object. If `member' is a regular file, a
 |      file-like object is returned. If `member' is a link, a file-like
 |      object is constructed from the link's target. If `member' is none of
 |      the above, None is returned.
 |      The file-like object is read-only and provides the following
 |      methods: read(), readline(), readlines(), seek() and tell()
Stefano Borini
fuente
Tenga en cuenta que, a continuación, puede acceder al miembro a través de un índice construido asímyFile = myArchive.extractfile( dict(zip(myArchive.getnames(), myArchive.getmembers()))['path/to/file'] ).read()
ThorSummoner
5

Una implementación de los métodos mencionados por @ stefano-borini Acceda a un miembro de archivos tar mediante un nombre de archivo como este

#python3
myFile = myArchive.extractfile( 
    dict(zip(
        myArchive.getnames(), 
        myArchive.getmembers()
    ))['path/to/file'] 
).read()`

Créditos:

ThorInvocador
fuente
0

puede usar tarfile.list () ex:

filename = "abc.tar.bz2"
with open( filename , mode='r:bz2') as f1:
    print(f1.list())

después de obtener estos datos. puede manipular o escribir esta salida en un archivo y hacer lo que sea que necesite.

ChandraShekhar Mahto
fuente