如何强制 unzip / zip 在解压时不创建子目录?

如何强制 unzip / zip 在解压时不创建子目录?

根据 zip 文件的创建方式,有时会直接提取所有文件,有时会将文件提取到子目录中。

如果后者为真,我如何强制命令unzip“忽略”该第一级目录?

例子:

cd /tmp
wget http://omeka.org/files/omeka-1.5.1.zip
mkdir omeka
unzip omeka-1.5.1.zip -d omeka/
cd omeka/
ll

我得到的是/tmp/omeka/omeka-1.5.1/

total 12
drwxr-xr-x 3 root root 4096 2012-05-08 18:44 ./
drwxrwxrwt 6 root root 4096 2012-05-08 18:44 ../
drwxr-xr-x 5 root root 4096 2012-04-20 14:54 omeka-1.5.1/

我想要的是提取到的文件/tmp/omeka/,(上一级,目录结构中不包含版本号)

/tmp/omeka/(files)

我知道我可以使用-j“垃圾路径”选项,但我想保留子目录结构,而不是顶级目录结构。我怎样才能做到这一点?

答案1

如果您的 zip 文件不包含目录结构或者您不需要保留它,您可以使用以下命令:

cd /tmp
wget http://omeka.org/files/omeka-1.5.1.zip
unzip -j omeka-1.5.1.zip -d omeka
cd omeka
ll

答案2

用一个保险丝文件系统,允许您像目录一样浏览档案,例如AVFS。用于cp将文件解压到您选择的目录。

mountavfs
cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/omeka-1.5.1 omeka

由于我们假设存档中有一个顶级目录,因此您可以将其缩短为

cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/* omeka

答案3

该脚本并不健壮,但适用于简单的情况:

...
dest=omeka
unzip omeka-1.5.1.zip -d $dest/

if [ `ls $dest | wc -l` == 1 ]; then
  subdir=`ls $dest`
  mv $dest/$subdir/* $dest/
  rmdir $dest/$subdir
fi

它只是检查是否存在一个子目录,如果是,则将所有内容移出其中,然后将其删除。

答案4

我今天刚刚注册,所以我无法对@SteveBennet 的答案进行投票,也无法在那里添加评论。

根据他的回答,我创建了一个像这样的递归函数:

...

shopt -s dotglob # To include hidden files in the move command

function moveSub {
  local dest=$1
  if [ `ls $dest | wc -l` == 1 ]; then
    local subdir=`ls $dest`
    moveSub "$dest/$subdir"
    mv $dest/$subdir/* $dest/
    rmdir $dest/$subdir
  fi
}

moveSub "$dest"

就像 @SteveBennet 所说:这个脚本并不健壮,但可以在简单的情况下工作。

希望它有用。

相关内容