在unix中解压一个目录

在unix中解压一个目录

我尝试了unzipUnix 中的一个文件夹:

$ unzip sample.zip

这正在创建根结构a/b/c/d/e/f/sample

我需要unzip当前目录中的一个文件夹。

答案1

unzip(1)手册页:

   -j     junk paths.  The archive's directory structure is not recreated;
          all files are deposited in the extraction directory (by default,
          the current one).

答案2

在没有完整层次结构的情况下解压缩文件夹

如果您只是尝试解压缩 zip 文件中某个目录的内容,而不保留该文件夹所在的任何层次结构,那么您就不走运了。没有方法可以提供此功能。问题在于 zip 文件的创建方式。它们通常被构建为固体斑点,因此并不像大多数人想象的那样容易访问。

我见过的唯一两种可以做到这一点的方法是创建一个遍历 zip 文件索引的循环,如下所示:

方法#1

for i in $(unzip -l zipfile.zip); do

   # look for specific location
   # when there, make directory structure you want
   # unzip zipfile.zip $i -d /some/tmp/dir
   # move file from /some/tmp/dir to new directory

done

上述操作可以用多种编程语言完成,例如 Perl、Python 等。

方法#2

另一种方法涉及制作 zip 文件的副本,然后使用该工具zipnote操作存档内文件的索引,然后在操作 zip 文件的索引后提取文件。

解压缩具有完整层次结构的文件夹

另一方面,如果您只是尝试从 zip 文件中提取单个文件夹,则可以使用以下命令来执行此操作:

$ unzip "/path/to/archive.zip" "in/archive/folder*" -d "/path/to/unzip/to"

例子

示例目录结构。

$ tree 
.
|-- 1
|   |-- 2
|   |   |-- 3
|   |   |   `-- 4
|   |   |       `-- 5
|   |   |           |-- file1
|   |   |           |-- file2
|   |   |           |-- file3
|   |   |           |-- file4
|   |   |           `-- file5
|   |   `-- afile
|   `-- afile
`-- afile

拉上拉链。

$ zip -r ../afile.zip .
  adding: afile (stored 0%)
  adding: 1/ (stored 0%)
  adding: 1/afile (stored 0%)
  adding: 1/2/ (stored 0%)
  adding: 1/2/afile (stored 0%)
  adding: 1/2/3/ (stored 0%)
  adding: 1/2/3/4/ (stored 0%)
  adding: 1/2/3/4/5/ (stored 0%)
  adding: 1/2/3/4/5/file1 (stored 0%)
  adding: 1/2/3/4/5/file2 (stored 0%)
  adding: 1/2/3/4/5/file3 (stored 0%)
  adding: 1/2/3/4/5/file5 (stored 0%)
  adding: 1/2/3/4/5/file4 (stored 0%)

确认 zip 文件的内容。

$ unzip -l ../afile.zip 
Archive:  ../afile.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  11-07-2013 16:43   afile
        0  11-07-2013 16:43   1/
        0  11-07-2013 16:43   1/afile
        0  11-07-2013 16:43   1/2/
        0  11-07-2013 16:43   1/2/afile
        0  11-07-2013 15:51   1/2/3/
        0  11-07-2013 15:51   1/2/3/4/
        0  11-07-2013 15:51   1/2/3/4/5/
        0  11-07-2013 15:51   1/2/3/4/5/file1
        0  11-07-2013 15:51   1/2/3/4/5/file2
        0  11-07-2013 15:51   1/2/3/4/5/file3
        0  11-07-2013 15:51   1/2/3/4/5/file5
        0  11-07-2013 15:51   1/2/3/4/5/file4
---------                     -------
        0                     13 files

现在我们只解压缩文件夹 5。

$ unzip afile.zip "1/2/3/4/5*" -d new/
Archive:  afile.zip
   creating: new/1/2/3/4/5/
 extracting: new/1/2/3/4/5/file1     
 extracting: new/1/2/3/4/5/file2     
 extracting: new/1/2/3/4/5/file3     
 extracting: new/1/2/3/4/5/file5     
 extracting: new/1/2/3/4/5/file4     

确认解压:

$ tree .
.
`-- 1
    `-- 2
        `-- 3
            `-- 4
                `-- 5
                    |-- file1
                    |-- file2
                    |-- file3
                    |-- file4
                    `-- file5

答案3

我认为您不能直接执行此操作,尽管可以通过将存档解压到临时位置并将文件移动到当前目录中来稍微迂回地完成此操作。

问题是你并不真正了解zip文件内容的结构,所以这很难解决在一般情况下。如果您想要做的只是“垃圾”第一个目录组件并将其下的所有内容都放入当前目录中,那么我们可以编写一个 shell 脚本或 shell 函数来完成它。我将向您展示一个 GNU bash 的示例;如果您更喜欢其他 shell,那么适应其他 shell 应该不难。您可以将其放在 ~/.bashrc 的末尾来尝试一下。

unzip_to_current_dir() {
  zipfilenames="$@"
  for zipfilename in ${zipfilenames}; do
    tempdir=$(mktemp -d)
    unzip -d "${tempdir}" "${zipfilename}"
    mv "${tempdir}/*/*" ./
    rm -rf "${tempdir}"
  done
}

想法是获取zip文件名,然后逐一创建一个临时目录,解压到该目录,将解压目标目录的第一级子目录中的所有内容移动到当前目录,然后清理临时目录在继续处理下一个文件之前。这有效地删除了 zip 文件中路径的第一个组成部分,因此解压包含 a/abc、a/bcd、a/cde 和 a/def/ghi 的 zip 文件时会将这些文件存储为 ./abc、./bcd 、./cde 和 ./def/ghi。

为了轻松测试这是否符合您的要求,请获取缩进最多的四行并手动执行它们,一次一行,仅将您自己的值替换为${zipfilename}。我强烈建议在不包含任何关键数据的目录中执行此操作;我非常怀疑该脚本中是否存在数据损坏错误,但是:如果它损坏了,您可以保留所有部分。

相关内容