如果zip归档文件包含多个文件,则创建目录


8

如果档案在根目录中包含多个文件,我想创建一个以文件名命名的目录(不带扩展名)。如果存档仅包含目录,那么我想简单地将其解压缩。假设我有以下档案:

# file: withdir.zip
somedir/alpha
somedir/beta
somedir/gamma

如果我将其解压缩到当前目录中,我希望将其简单地解压缩(unzip withdir.zip):

somedir/alpha
somedir/beta
somedir/gamma

现在假设以下存档:

# file: nodir.zip
alpha
beta
gamma

当我运行时unzip nodir.zip,最终将三个文件弄乱了当前目录:

alpha
beta
gamma

我宁愿跑unzip -d nodir nodir.zip

nodir/alpha
nodir/beta
nodir/gamma

如果我使用鹦鹉螺,请右键单击“在此处提取”。它的行为完全正确。但是不幸的是,我还没有找到一个命令行开关,unzip或者没有 7z产生相同的行为。如何实现呢?还有其他我可以使用的工具(没有GUI)吗?

Answers:


7

我会做这样的事情(zsh语法):

unz() (
  tmp=$(TMPDIR=. mktemp -d -- ${${argv[-1]:t:r}%.tar}.XXXXXX) || exit
  print -r >&2 "Extracting in $tmp"
  cd -- $tmp || exit
  [[ $argv[-1] = /* ]] || argv[-1]=../$argv[-1]
  (set -x; "$@"); ret=$?
  files=(*(ND[1,2]))
  case $#files in
    (0) print -r >&2 "No file created"
        rmdir -v "../$tmp";;
    (1) mv -v -- $files .. && rmdir -v ../$tmp;;
    (*) mv -vT ../$tmp ../$tmp:r;;
  esac && exit $ret
)

那是:

  1. 无论如何创建目录
  2. 运行命令
  3. 根据命令生成的文件数量而定:
    • 删除该目录(如果未创建任何文件)
    • 如果它仅创建一个文件/目录,则将其上移一级并丢弃目录
    • 否则,尝试从temp目录的末尾剥离随机字符串。

这样,您可以执行以下操作:

unz unzip foo.zip
unz tar xf foo.tar.gz

假定解压缩命令的最后一个参数是要解压缩的文件。它还假定使用GNU工具作为-v选项。在非GNU系统上,您可以删除它们并可以手动进行日志记录。mv -T也是GNU特定的,并且强制mv尝试仅重命名。


3

由于unzip7z都有一个开关,输出到给定的目录,你可以创建一个简单的脚本,支票,许多文件是如何在归档文件的根目录,然后根据需要添加开关。

使用7z,由于具有-slt开关,因此更容易实现,从而使输出更易于机读。对于zip中的每个文件,输出将包含Path = ...一行。根目录中的文件不应包含任何/值。

我写的一个简单脚本以这种方式解压缩文件:

#!/bin/sh
for archive in "$@"; do
    # count files in root dir
    rootfiles=$(7z l -slt "${archive}" | grep -c 'Path = [^/]*$')

    # add -o switch, if more than one file in root
    # checks for >2, because path of the zip file itself is listed too
    if [ $rootfiles -gt 2 ]; then
        filename=${archive##*/}
        rootname=${filename%.*}
        opt="-o${rootname}"
    fi

    #unpack
    7z x "${opt}" "${archive}"
done

编辑:脚本现在也适用于zip


该脚本无法正常工作。它创建一个目录withdir存档withdir.zip尽管它包含根,因为只是一个目录grep -c "Folder = -"的回报3
Marco Marco

啊,文件夹似乎与zip文件不同。我将寻找解决方法
crater2150

@Marco:我更改了脚本并使用zip文件进行了测试,现在它仅在需要时创建文件夹
crater2150 2013年

3

如果归档文件包含多个文件,则patool会处理各种类型的归档文件并创建一个子目录,以防止提取的文件使工作目录混乱。

创建档案

patool create archive.zip somedirectory

提取档案

patool extract archive.zip

要获取支持的格式列表,请使用patool formats


1

您还可以使用unar,当存在两个或更多顶级文件时,默认情况下会创建一个包含目录:

$ touch 1 2
$ zip a.zip 1 2
  adding: 1 (stored 0%)
  adding: 2 (stored 0%)
$ unzip -l a.zip
Archive:  a.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  04-29-14 10:56   1
        0  04-29-14 10:56   2
 --------                   -------
        0                   2 files
$ unar a.zip
a.zip: Zip
  1  (0 B)... OK.
  2  (0 B)... OK.
Successfully extracted to "a".
$ ls a
1 2

添加-d以始终创建一个包含目录。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.