В R получите текст и соответствующее имя файла каждого файла в ZIP-архиве. - PullRequest
0 голосов
/ 13 мая 2019

У меня есть несколько ZIP-архивов, каждый из которых содержит несколько текстовых файлов.Я хочу прочитать весь текст в память, по одной строке на файл, и каждый файл помечается соответствующим именем файла, но без удаления исходных файлов ZIP или записи всего содержимого на диск.(Если запись временных файлов является обязательной, их следует удалить после того, как мы закончим их читать или если обработка прервана.)

Например, предположим, что вы создаете простой ZIP-файл, подобный этому:

$ echo 'contents1' > file1
$ echo 'contents2' > file2
$ zip files.zip file1 file2

Затем вызов myfunction("files.zip") должен вернуть то же самое, что и list(file1 = "contents1\n", file2 = "contents2\n").

В настоящее время я использую следующую функцию, которая использует Info-ZIP unzip.Он работает нормально, за исключением того, что его код, определяющий конец одного файла и начало другого, может сработать вместо содержимого файла.

library(stringr)

slurp.zip = function(path)
  # Extracts each file in the zip file at `path` as a single
  # string. The names of the resulting list are set to the inner
  # file names.
   {lines = system2("unzip", c("-c", path), stdout = T)
    is.sep = str_detect(lines, "^ (?: inflating|extracting): ")
    chunks = lapply(
        split(lines[!is.sep], cumsum(is.sep)[!is.sep])[-1],
        function(chunk) paste(chunk, collapse = "\n"))
    fnames = str_match(lines[is.sep], "^ (?: inflating|extracting): (.+)  $")
    stopifnot(!anyNA(fnames))
    names(chunks) = fnames[,2]
    chunks}

1 Ответ

1 голос
/ 17 мая 2019

Мы можем использовать unzip(..., list = TRUE), чтобы получить имена файлов в архиве, фактически не извлекая их. Затем мы можем использовать unz для создания соединений с файлами, которые можно прочитать, например, с помощью. readLines или scan:

slurp.zip = function(path) {
  sapply(unzip(path, list = TRUE)$Name, function(x) 
    paste0(readLines(unz('files.zip', x)), collapse = '\n'), 
    simplify =  FALSE, USE.NAMES = TRUE)
}

dput(slurp.zip('files.zip'))
# list(file1 = "contents1\n", file2 = "contents2\n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...