2013-12-06 3 views
0

Мне нужно получить пару файлов из огромного репозитория svn. Целая репо занимает почти час, чтобы ее можно было получить. Файлы, которые я ищу, являются частью пакета tar.Возможно ли извлечь один файл из пакета tar в python

Возможно ли получить только эти два файла из пакета tar без извлечения всего пакета через код Python?

Если да, может ли кто-нибудь сообщить мне, как мне это сделать?

+0

Вам не нужно Python извлекать отдельные файлы из архива. 'man tar', чтобы найти нужные вам параметры. Конечно, вам нужен tarball, прежде чем вы сможете манипулировать им ... – MattDMo

+0

MattDMo Мне нужно сделать это программно, и мой архив находится в svn repo. –

ответ

0

Вот один из способов, чтобы получить деготь файл из SVN и извлечь один файл из всего этого:

import tarfile 
from subprocess import check_output 
# Capture the tar file from subversion 
tmp='/home/me/tempfile.tar' 
open(tmp, 'wb').write(check_output(["svn", "cat", "svn://url/some.tar"])) 
# Extract the file we want, saving to current directory 
tarfile.open(tmp).extract('dir1/fname.ext', path='dir2') 

где «dir1/fname.ext» полный путь к файлу, который вам в архиве tar. Он будет сохранен в 'dir2/dir1/fname.ext'. Если вы опустите аргумент path, он будет сохранен в 'dir1/fname.ext' в текущем каталоге.

Вышеуказанное можно понять следующим образом. В командной строке с нормальной оболочкой svn cat url сообщает subversion отправить файл, определенный url в stdout (см. svn help cat для получения дополнительной информации). url может быть любым типом URL, который понимает svn, например svn://..., svn+ssh://..., или file://.... Мы запускаем эту команду под управлением python с помощью модуля подпроцесса. Для этого команда svn cat url распадается на список: ["svn", "cat", "url"]. Результат этой команды svn сохраняется в локальном файле, определяемом переменной tmp. Затем мы используем модуль tarfile для извлечения нужного файла.

В качестве альтернативы, вы можете использовать метод extractfile для захвата данных из файла в переменную питона:

handle = t.extractfile('dir1/fname.ext') 
print handle.readlines() # show file contents 

Согласно документации, файл обработан должен принять стандартный вывод Подпроцесса в качестве дескриптора файла. Это упростит код и устранит необходимость сохранения файла tar локально. Однако из-за ошибки Issue 10436 это не сработает.

+0

Поблагодарите John1024 за выбор tar-файла, мой вызов будет таким, t.extract ('dir/fname.ext'), правильно? также можно удаленно читать/извлекать tar-файл. Я имею в виду от svn repo? –

+0

Да на синтаксисе 'extract'. Вы можете использовать модуль python 'pysvn' для получения файла tar через svn. Например, см. [Http://pysvn.tigris.org/docs/pysvn_prog_guide.html]. – John1024

+0

@RajanPathak Я только что обновил ответ методом, который начинается с извлечения tar-файла через svn. – John1024

1

Возможно, вы хотите что-то подобное?

#!/usr/local/cpython-3.3/bin/python 

import tarfile as tarfile_mod 

def main(): 
    tarfile = tarfile_mod.TarFile('tar-archive.tar', 'r') 
    if False: 
     file_ = tarfile.extractfile('etc/protocols') 
     print(file_.read()) 
    else: 
     tarfile.extract('etc/protocols') 
    tarfile.close() 

main() 
+0

Спасибо, dstromberg за ваш ответ, файл протоколов будет загружен в рабочую директорию cureent, правильно? Может ли tarball читать на svn удаленном репо? –

+0

Может ли извлечь в память или на диск; ваше предпочтение.Если вы хотите прочитать файл из SVN, и вы работаете в Linux, вы можете попробовать svnfs: http://www.jmadden.eu/index.php/svnfs/. Если вы не используете Linux или хотите избежать создания новой файловой системы, вы можете «svn экспортировать http://host.name.com/dir/file.tar» перед использованием приведенного выше кода. – dstromberg

1

Похоже, у вас есть две части на ваш вопрос:

  1. Извлечение одного дегтя сверток из репо SVN, без остальных файлов в репо.
  2. Использование Python для извлечения двух файлов из извлеченного пакета.

Для первой части, я просто сослаться на this postsvn export и разреженных извлечений.

Для второй части, то здесь решение для извлечения двух файлов из извлеченного архива:

import tarfile 

files_i_want = ['path/to/file1','path/to/file2'] 

tar = tarfile.open("bundle.tar") 
tar.extractall(members=[x for x in tar.getmembers() if x.name in files_i_want]) 
Смежные вопросы