czytanie zawartości pliku tar bez rozpakowywania go w skrypcie Pythona

82

Mam plik tar, który zawiera wiele plików. Muszę napisać skrypt w Pythonie, który odczyta zawartość plików i poda liczbę wszystkich znaków, w tym całkowitą liczbę liter, spacji, znaków nowej linii, wszystko, bez rozpakowywania pliku tar.

randeepsp
źródło
Jak możesz policzyć znaki / litery / spacje / cokolwiek bez wyodrębniania ich gdzie indziej?
TY
16
to jest właśnie zadane pytanie.
Erik Kaplun,

Odpowiedzi:

127

możesz użyć getmembers()

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

Następnie możesz użyć extractfile()do wyodrębnienia podzbiorów jako obiektu pliku. Tylko przykład

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()

Z obiektu pliku fw powyższym przykładzie, można użyć read(), readlines()etc.

ghostdog74
źródło
17
„for member in tar.getmembers ()” można zmienić na „for member in tar”, który jest generatorem lub iteratorem (nie jestem pewien który). Ale dostaje jednego członka na raz.
przytulanie
2
Właśnie miałem podobny problem, ale moduł tarfile wydaje się zjadać mój RAM, mimo że użyłem tej 'r|'opcji.
devsnd
2
Ach. Rozwiązałem to. Zakładając, że napiszesz kod zgodnie ze wskazówkami huggie, musisz od czasu do czasu „wyczyścić” listę członków. Biorąc więc pod uwagę powyższy przykład kodu, byłoby to tar.members = []. Więcej informacji tutaj: bit.ly/JKXrg6
devsnd
zostanie tar.getmembers()wywołany wiele razy, gdy zostanie umieszczony w for member in tar.getmembers()pętli?
Haifeng Zhang
1
Czy po wykonaniu polecenia „f = tar.extractfile (element członkowski)” należy również zamknąć f?
bolei
12

musisz użyć modułu tarfile. W szczególności używasz wystąpienia klasy TarFile, aby uzyskać dostęp do pliku, a następnie uzyskać dostęp do nazw za pomocą 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().

Jeśli zamiast tego chcesz przeczytać treść , użyj tej metody

 |  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
źródło
Uwaga, możesz wtedy uzyskać dostęp do członka za pośrednictwem indeksu skonstruowanego w ten sposóbmyFile = myArchive.extractfile( dict(zip(myArchive.getnames(), myArchive.getmembers()))['path/to/file'] ).read()
ThorSummoner
5

Implementacja metod wymienionych przez @ stefano-borini Dostęp do członka archiwum tar poprzez nazwę pliku w ten sposób

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

Kredyty:

ThorSummoner
źródło
0

możesz użyć tarfile.list () ex:

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

po otrzymaniu tych danych. możesz manipulować tym wyjściem lub zapisywać je do pliku i robić wszystko, czego potrzebujesz.

ChandraShekhar Mahto
źródło