【问题标题】:Sys.glob () within unzip ()unzip() 内的 sys.glob()
【发布时间】:2015-09-17 17:19:09
【问题描述】:

TLDNR:如何在 unzip () 中使用 Sys.glob ()?

我有多个 .zip 文件,我只想从每个存档中提取一个文件。

例如,其中一个档案包含以下文件:

[1] "cmc-20150531.xml"     "cmc-20150531.xsd"     "cmc-20150531_cal.xml" "cmc-20150531_def.xml" "cmc-20150531_lab.xml"
[6] "cmc-20150531_pre.xml"

我想提取第一个文件,因为它匹配一个模式。为此,我使用以下命令:

unzip("zip-archive.zip", files=Sys.glob("[a-z][a-z][a-z][-][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.][x][m][l]"))

但是,该命令不起作用,我不知道为什么。 R 只是提取档案中的所有文件。

另一方面,以下命令有效:

unzip("zip-archive.zip", files="cmc-20150531.xml")

如何在 unzip() 中使用 Sys.glob()?

【问题讨论】:

  • 那是哪种编程语言?

标签: r unzip glob


【解决方案1】:

Sys.glob 扩展已存在的文件。因此,unzip 调用的参数将取决于工作目录中的文件。

也许你想用list=TRUEunzip 以首先返回zip 中的文件列表,然后使用一些模式匹配来选择你想要的文件。

有关将字符串与模式匹配的信息,请参阅?grep。这些模式是“正则表达式”而不是“glob”扩展,但您应该能够使用它。

这是一个具体的例子:

# whats in the zip?
files = unzip("c.zip", list=TRUE)$Name
files
[1] "l_spatial.dbf"    "l_spatial.shp"    "l_spatial.shx"    "ls_polys_bin.dbf"
[5] "ls_polys_bin.shp" "ls_polys_bin.shx" "rast_jan90.tif"  

# what files have "dbf" in them:
files[grepl("dbf",files)]
[1] "l_spatial.dbf"    "ls_polys_bin.dbf"

# extract just those:
unzip("c.zip", files=files[grepl("dbf",files)])

glob 的正则表达式

 "[a-z][a-z][a-z][-][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.][x][m][l]"

 "^[a-z]{3}-[0-9]{8}\\.xml$"

这是字符串开头 ("^")、3 az(仅限小写字母)、破折号、八位数字、一个点(需要反斜杠,一个是因为点在正则表达式中表示“任何一个字符”)和另一个因为 R 需要一个反斜杠来转义反斜杠)、“xml”和字符串的结尾(“$”)。

【讨论】:

  • 行得通!除了,我认为你需要使用unzip("c.zip", files=files$Names[grepl("dbf",files$Names)])。您使用的第一个命令返回一个数据框,而不是一个列表。因此,您需要指定具有名称的列。除此之外,代码有效!
【解决方案2】:

只需与任何其他集合一起对 Sys.glob 的结果进行迭代循环,并提供迭代保存变量以解压缩。这是通过使用for-loop

来实现的

unzip() 接受路径参数,而 files 是该 zip 文件中哪些文件的参数。

挖掘你我更像是一个全栈程序员,而不是 R 语言,但概念是相同的;所以代码应该是这样的:

files <- Sys.glob(path_expand(".","*.zip"))
for (idx in 1:length(files)) {
    results = unzip(files[idx], "*.xml")
}

至于在unzip() 中使用正则表达式,应该阅读文档。我只能建议再做一次for-loop 将 zip 文件的竞争与您的正则表达式进行比较,然后进行提取。伪代码如下:

files ::= glob(*.zip)
regex ::= 
for idx1 in length(files); do
  regex="[a-z]{3}\-[0-9]{8}\.xml"
  content = unzip(files[idx1])
  for idx2 in length(content); do
    if content[idx2].name ~= regex.expand(); then
      # do something with found file
    end if
  end for
end for

基本上,您只需遍历 zip 文件列表,然后遍历 zip 文件中的文件列表,并比较 zipfile 中的文件名,代理正则表达式并仅对该文件进行提取/执行操作。

【讨论】:

  • 不,与命令行解压缩不同,R 的解压缩功能只进行精确的文件名匹配。您不能在 R 中执行 unzip("foo.zip","*.dbf"),但您可以在 shell 命令行中执行 unzip foo.zip '*.dbf'
  • @Spacedman 确切地说,这就是为什么有显示循环和比较的扩展伪代码的原因。 R 不是我的主要语言,但它在程序上与 C、Ruby 和其他更高级别的语言相同。因此,如果上面带有 `unzip(files[idx], "*.xml") 的示例不完整,那是因为我正在尝试使用 OP RTMF 并可能同时将它们引导到正确的方向
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多