Buat direktori jika arsip zip berisi beberapa file

8

Jika arsip berisi beberapa file di direktori root, saya ingin membuat direktori bernama setelah nama file (tanpa ekstensi). Jika arsip hanya berisi direktori, maka saya ingin mengekstraknya. Asumsikan saya memiliki arsip berikut:

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

Jika saya mengekstraknya di direktori saat ini saya ingin memilikinya cukup diekstraksi ( unzip withdir.zip):

somedir/alpha
somedir/beta
somedir/gamma

Sekarang anggap arsip berikut:

# file: nodir.zip
alpha
beta
gamma

Ketika saya menjalankan unzip nodir.zipsaya berakhir mengacaukan direktori saat ini dengan tiga file:

alpha
beta
gamma

Saya lebih suka berlari unzip -d nodir nodir.zip:

nodir/alpha
nodir/beta
nodir/gamma

Jika saya menggunakan nautilus dan klik kanan pada "Extract Here". Berperilaku tepat seperti yang seharusnya. Tapi sayangnya saya belum menemukan saklar baris perintah untuk unzipatau 7zyang menghasilkan perilaku yang sama. Bagaimana cara mencapainya? Apakah ada alat lain yang bisa saya gunakan (tidak ada GUI)?

Marco
sumber

Jawaban:

7

Saya akan melakukan sesuatu seperti ini (sintaks 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
)

Itu adalah:

  1. buat direktori di tas apa saja
  2. jalankan perintah
  3. tergantung pada berapa banyak file yang dihasilkan oleh perintah:
    • hapus direktori itu (jika tidak membuat file apa pun)
    • jika hanya membuat satu file / dir, pindahkan satu tingkat ke atas dan buang direktori kami
    • jika tidak, cobalah untuk menghapus string acak dari akhir direktori temp kami.

Dengan cara ini, Anda dapat melakukan:

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

Itu mengasumsikan bahwa argumen terakhir untuk perintah ekstraksi adalah file untuk diekstraksi. Ini juga mengasumsikan alat GNU untuk -vopsi. Pada sistem non-GNU, Anda dapat menghapusnya dan mungkin melakukan logging dengan tangan. mv -Tjuga spesifik GNU, dan memaksa mvuntuk mencoba melakukan penggantian nama saja.

Stéphane Chazelas
sumber
3

Karena unzipdan 7zkeduanya memiliki peralihan ke keluaran ke direktori yang diberikan, Anda dapat membuat skrip sederhana, yang memeriksa, berapa banyak file yang ada di root arsip dan kemudian menambahkan peralihan jika diperlukan.

Dengan 7z ini lebih mudah, karena memiliki -sltsaklar, yang membuat output lebih mudah dibaca mesin. Untuk setiap file di zip, output akan berisi satu Path = ...baris. File di root tidak boleh mengandung nilai apa pun /.

Sebuah skrip sederhana yang saya tulis untuk membongkar file seperti itu:

#!/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

Sunting: skrip sekarang berfungsi dengan zip juga

crater2150
sumber
Script ini tidak berfungsi seperti yang diharapkan. Itu membuat direktori withdiruntuk arsip withdir.zipwalaupun hanya berisi satu direktori di root karena grep -c "Folder = -"kembali 3.
Marco
ah, Folder sepertinya berbeda untuk file zip. Saya akan mencari perbaikan
crater2150
@ Marsco: Saya mengubah skrip dan mengujinya dengan file zip, sekarang hanya membuat folder bila diperlukan
crater2150
3

patool menangani berbagai jenis arsip dan membuat subdirektori seandainya arsip tersebut berisi banyak file untuk mencegah kekacauan direktori kerja dengan file yang diekstraksi.

Buat arsip

patool create archive.zip somedirectory

Ekstrak arsip

patool extract archive.zip

Untuk mendapatkan daftar format yang didukung, gunakan patool formats.

Marco
sumber
1

Anda juga bisa menggunakan unar , yang membuat direktori berisi secara default ketika ada dua atau lebih file tingkat atas:

$ 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

Tambah -duntuk selalu membuat direktori yang berisi.

Lri
sumber