在 R 中解压受密码保护的 zip 文件

Unzip password protected zip files in R

无法在 unzip (utils) 函数中指定密码。我知道的另一个函数 getZip (Hmisc) 仅适用于包含一个压缩文件的 zip 文件。

我想做这样的事情来解压 Windows 中 foo.zip 中的所有文件 8:

unzip("foo.zip", password = "mypass")

我发现这个问题非常有用,但看到没有发布正式的答案,所以这里是:

  1. 首先我安装了 7z。
  2. 然后我将“C:\Program Files-Zip”添加到我的环境路径中。
  3. 我测试了 7z 命令可以从命令行识别。
  4. 我打开 R 并输入 system("7z x secure.7z -pPASSWORD") 和适当的 PASSWORD

我有多个压缩文件,我不希望密码显示在源代码中或存储在任何文本文件中,所以我编写了以下脚本:

file_list <- list.files(path = ".", pattern = ".7z", all.files = T)
pw <- readline(prompt = "Enter the password: ")
for (file in file_list) {
  sys_command <- paste0("7z ", "x ", file, " -p", pw)
  system(sys_command)
}

获取时会提示我输入密码,zip 文件会循环解压。

password <- "your password"
system(
  command = paste0("unzip -o -P ", password, " ", "yourfile.zip"), 
  wait = TRUE
)
password <- "your password"
read.table(
  text = system(paste0("unzip -p -P ", password, " yourfile.zip ", "yourfile.csv"),
    intern = "TRUE"
  ), stringsAsFactors = FALSE, header = TRUE, sep = ","
)

我发现@Kim 的回答最终对我有用,但不是一开始。我想我应该添加一些额外的 links/steps 来帮助我最终实现目标。

关闭并重新打开 R 以便识别环境路径

如果您在执行步骤 1-3 时已经打开 R,则需要关闭并重新加载 R,以便 R 识别 7z 的环境路径。 @wush978 对这个问题 r system doesn't work when trying 7zip 的回答很有启发性。我使用 Sys.getenv("PATH") 检查环境路径中是否包含 7zip。

第 4 步。我打开 R 并输入 system("7z x secure.7z -pPASSWORD") 和相应的密码。

我实际上发现这不起作用,所以我按照 post 中的说明稍微修改了它,其中还解释了如何指定输出目录 。

如果您已经提取文件,系统命令会提示您选择是否要用存档中的文件替换现有文件并提供选项 (Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit?

所以修改后的第4步(Y允许替换文件)

system("7z e -ooutput_dir secure.zip -pPASSWORD" Y)

将其作为一组修改后的指令

  1. 安装 7z。
  2. 使用菜单选项将 "C:\Program Files-Zip\" 添加到我的环境路径(此处的说明 https://www.opentechguides.com/how-to/article/windows-10/113/windows-10-set-path.html
  3. 关闭并重新打开 R studio。输入 Sys.getenv("PATH") 以检查环境中识别的 7zip 路径(根据@wush978 对问题 r system doesn't work when trying 7zip 的回答)
  4. 在控制台中输入 system("7z e -oC:/My Documents/output_dir secure.zip -pPASSWORD") 和适当的密码(按照此处的说明 )

这里是@Kim 简洁功能的修改版本(包括指定的输出目录和检查现有文件):

我的主脚本

output_dir <- "C:/My Documents/output_dir " #space after directory name is important
zippedfiles_dir <- "C:/My Documents/zippedfiles_dir/"

file_list <- paste0(output_dir , zippedfiles_dir , list.files(path = zippedfiles_dir, pattern = ".zip", all.files = T))

source("unzip7z.R")

源文件中的代码unzip7z.R

pw = readline(prompt = "Enter the password: ")
for (file in file_list) {
  csvfile <- gsub("\.zip", "\.csv", gsub(".*? ", "", file)) #csvfile name (removes output_dir from 'file' and replaces .zip extension with .csv)

#check if csvfile already exists in output_dir, and if it does, replace it with archived version and if it doesn't exist, continue to extract.
  if(file.exists(csvfile)) { 
     sys_command = paste0("7z ", "e -o", file, " -p", pw, " Y")
  } else {
     sys_command = paste0("7z ", "e -o", file, " -p", pw)
  } 
  system(sys_command)
}