Lesen von Inhalten von TAR-Dateien, ohne sie zu entkernen, in Python-Skript

81

Ich habe eine TAR-Datei, die die Anzahl der Dateien enthält. Ich muss ein Python-Skript schreiben, das den Inhalt der Dateien liest und die Anzahl der Gesamtzeichen angibt, einschließlich der Gesamtzahl der Buchstaben, Leerzeichen, Zeilenumbrüche usw., ohne die Teer-Datei zu entkernen.

randeepsp
quelle
Wie können Sie die Zeichen / Buchstaben / Leerzeichen / alles zählen, ohne diese an einen anderen Ort zu extrahieren?
SIE
16
Das ist genau die Frage, die gestellt wird.
Erik Kaplun

Antworten:

126

Sie können verwenden getmembers()

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

Danach können Sie extractfile()die Mitglieder als Dateiobjekt extrahieren. Nur ein Beispiel

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

Mit dem Dateiobjekt fin dem obigen Beispiel können Sie verwenden read(), readlines()usw.

Ghostdog74
quelle
16
"für Mitglied in tar.getmembers ()" kann in "für Mitglied in tar" geändert werden, das entweder ein Generator oder ein Iterator ist (ich bin nicht sicher, welcher). Aber es bekommt ein Mitglied nach dem anderen.
Huggie
2
Ich hatte gerade ein ähnliches Problem, aber das Tarfile-Modul scheint meinen Widder zu fressen, obwohl ich die 'r|'Option verwendet habe.
devsnd
2
Ah. Ich habe es gelöst. Angenommen, Sie schreiben den Code wie von huggie angedeutet, müssen Sie die Liste der Mitglieder von Zeit zu Zeit "bereinigen". In Anbetracht des obigen Codebeispiels wäre das also tar.members = []. Weitere Infos hier: bit.ly/JKXrg6
devsnd
wird tar.getmembers()mehrmals aufgerufen, wenn es in eine for member in tar.getmembers()Schleife gestellt wird?
Haifeng Zhang
1
Müssen Sie nach "f = tar.extractfile (member)" auch f schließen?
Bolei
12

Sie müssen das Tarfile-Modul verwenden. Insbesondere verwenden Sie eine Instanz der Klasse TarFile, um auf die Datei zuzugreifen, und greifen dann mit TarFile.getnames () auf die Namen zu.

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

Wenn Sie stattdessen den Inhalt lesen möchten , verwenden Sie diese Methode

 |  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
quelle
Beachten Sie, dass Sie dann über einen so erstellten Index auf das Mitglied zugreifen könnenmyFile = myArchive.extractfile( dict(zip(myArchive.getnames(), myArchive.getmembers()))['path/to/file'] ).read()
ThorSummoner
5

Eine Implementierung der von @ stefano-borini genannten Methoden Greifen Sie über einen solchen Dateinamen auf ein Mitglied des Tar-Archivs zu

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

Credits:

ThorSummoner
quelle
0

Sie können tarfile.list () verwenden, z.

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

nachdem Sie diese Daten erhalten haben. Sie können diese Ausgabe bearbeiten oder in eine Datei schreiben und alles tun, was Sie benötigen.

ChandraShekhar Mahto
quelle