2

I regularly got suckered by zip file (libraries, programs, ...).

Sometime, I am cautious and I do:

$ mkdir content && cd content
$ unzip ../library.zip
Archive: library.zip
 creating: library/
inflating: library/foo.c
...
$ # Grumble...
$ mv library/* .
$ rmdir library

Sometime I get lazy and I simply do...

$ cd
$ unzip ../library.zip
Archive: library.zip
 creating: config/
inflating: config/...
 creating: lib/
 creating: bin/
 creating: ...
...
$ # Grumble...
$ mkdir library
$ mv config library
$ mv lib library
$ mv bin library
$ # ...

Is there an universal way to unzip a zip file without falling into either of these issues?

2 Answers 2

1

I agree that this is super annoying. I think unzip should support it out of the box. Here's a script that will get the job done (I call it unzipd).

#!/usr/bin/env bash

# Exit on any error
set -e

# Check we have at least one argument
if [ $# -ne 1 ]; then
  echo "Missing zip filename parameter"
  exit 2
fi

zip="$1"
# Get filename only (no path)
zipfile=${zip##*/}
# Get file base namem (no extension)
zipbase=${zipfile%%.*}

# Make a tmp dir in the current dir
tmpdir=$(mktemp -d -p . -t "$zipbase.XXXX")

# Unzip into the tmp directory
/usr/bin/unzip -d "$tmpdir" ${@:1:$(($#-1))} "$zip"

# Check number of files in the tmp dir
if [ "$(ls -1 "$tmpdir" | wc -l)" -eq 1 ]; then
  # If there's only 1 file in the tmp, move it up a level
  mv "$tmpdir"/* .
  # Get rid of tmp dir
  rmdir "$tmpdir"
else
  # If more then 1 file, just rename the tmp dir based on the zip filename
  mv "$tmpdir" "$zipbase"
fi
1

Prior to unzipping, you can use unzip with option -l first, in order to check if all zipped files are under a common folder in the archive.

2
  • 1
    unzip -l <archive.zip> | awk 'NR==4{print $1}' prints the size of the first element in the archive, 0 in case of a directory. (Works for me with Info-ZIP UnZip 6.00).
    – ischeriad
    Commented Mar 27, 2018 at 14:06
  • @ischeriad Unfortunately, this does not cover all cases. Specifically, if a zip happens to have a dirs and files and the first element alphabetically is a dir, you will get a false positive. Not to mention that files can have a zero size as well.
    – oneself
    Commented Mar 17, 2019 at 22:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .