чтение содержимого tar-файла без его распаковки в скрипте Python

82

У меня есть tar-файл, в котором есть несколько файлов. Мне нужно написать скрипт Python, который будет читать содержимое файлов и давать общее количество символов, включая общее количество букв, пробелов, символов новой строки и т. Д., Без распаковки tar-файла.

рандепсп
источник
Как вы можете подсчитать символы / буквы / пробелы / все, не извлекая их в другое место?
ВЫ
16
это именно тот вопрос.
Эрик Каплун

Ответы:

127

вы можете использовать getmembers()

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

После этого вы можете использовать extractfile()для извлечения членов как файлового объекта. Просто пример

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

С файловым объектом fв приведенном выше примере вы можете использовать read()и readlines()т. Д.

призрачная собака74
источник
17
«для члена в tar.getmembers ()» можно изменить на «для члена в tar», который является либо генератором, либо итератором (я не уверен, какой именно). Но он получает по одному члену за раз.
huggie
2
У меня была аналогичная проблема, но модуль tarfile, похоже, съел мою память, хотя я использовал эту 'r|'опцию.
devsnd
2
Ах. Я решил это. Предполагая, что вы напишете код, как намекает Хагги, вам нужно время от времени «очищать» список участников. Итак, учитывая приведенный выше пример кода, это будет tar.members = []. Подробнее здесь: bit.ly/JKXrg6
devsnd
будет tar.getmembers()вызываться несколько раз при включении for member in tar.getmembers()цикла?
Хайфэн Чжан,
1
После того, как вы выполните "f = tar.extractfile (member)", нужно ли вам также закрыть f?
bolei
12

вам нужно использовать модуль tarfile. В частности, вы используете экземпляр класса TarFile для доступа к файлу, а затем получаете доступ к именам с помощью 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().

Если вместо этого вы хотите прочитать содержимое , используйте этот метод

 |  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()
Стефано Борини
источник
Обратите внимание, что затем вы можете получить доступ к члену через индекс, построенный следующим образомmyFile = myArchive.extractfile( dict(zip(myArchive.getnames(), myArchive.getmembers()))['path/to/file'] ).read()
ThorSummoner
5

Реализация методов, упомянутых @ stefano-borini Доступ к члену tar-архивов через имя файла, например

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

Кредиты:

ТорСаммонер
источник
0

вы можете использовать tarfile.list () например:

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

после получения этих данных. вы можете манипулировать или записывать этот вывод в файл и делать все, что вам нужно.

ЧандраШекхар Махто
источник