Tạo thư mục nếu kho lưu trữ zip chứa một số tệp


8

Nếu kho lưu trữ chứa một số tệp trong thư mục gốc, tôi muốn tạo một thư mục được đặt tên theo tên tệp (không có phần mở rộng). Nếu một kho lưu trữ chỉ chứa một thư mục, thì tôi chỉ muốn giải nén nó. Giả sử tôi có kho lưu trữ sau:

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

Nếu tôi giải nén nó trong thư mục hiện tại, tôi chỉ muốn giải nén nó ( unzip withdir.zip):

somedir/alpha
somedir/beta
somedir/gamma

Bây giờ giả sử kho lưu trữ sau:

# file: nodir.zip
alpha
beta
gamma

Khi tôi chạy, unzip nodir.zipcuối cùng tôi làm lộn xộn thư mục hiện tại với ba tệp:

alpha
beta
gamma

Tôi thà chạy unzip -d nodir nodir.zip:

nodir/alpha
nodir/beta
nodir/gamma

Nếu tôi sử dụng nautilus và nhấp chuột phải vào trích xuất ở đây. Nó hành xử chính xác như nó cần. Nhưng thật không may, tôi đã không tìm thấy một chuyển đổi dòng lệnh cho unziphoặc 7zmang lại hành vi tương tự. Làm thế nào để đạt được điều đó? Có công cụ nào khác tôi có thể sử dụng thay thế (không có GUI) không?

Câu trả lời:


7

Tôi sẽ làm một cái gì đó như thế này (cú pháp 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
)

Đó là:

  1. tạo một thư mục trong anycase
  2. chạy lệnh
  3. tùy thuộc vào số lượng tập tin lệnh được tạo:
    • xóa thư mục đó (nếu nó không tạo bất kỳ tập tin nào)
    • nếu nó chỉ tạo một tập tin / thư mục, hãy di chuyển nó lên một cấp và loại bỏ thư mục của chúng tôi
    • mặt khác, cố gắng tách chuỗi ngẫu nhiên từ cuối thư mục tạm thời của chúng tôi.

Bằng cách này, bạn có thể làm:

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

Nó giả định rằng đối số cuối cùng cho lệnh giải nén là tệp cần giải nén. Nó cũng giả sử các công cụ GNU cho các -vtùy chọn. Trên các hệ thống không phải GNU, bạn có thể xóa chúng và có thể thực hiện ghi nhật ký bằng tay. mv -Tcũng là đặc trưng của GNU và chỉ buộc mvphải thử đổi tên.


3

unzip7zcả hai đều có một công tắc để xuất ra một thư mục nhất định, bạn có thể tạo một tập lệnh đơn giản, kiểm tra xem có bao nhiêu tệp trong thư mục gốc của kho lưu trữ và sau đó thêm công tắc nếu cần.

Với 7z thì điều này dễ dàng hơn, vì nó có công -slttắc, giúp đầu ra dễ đọc hơn. Đối với mỗi tệp trong zip, đầu ra sẽ chứa một Path = ...dòng. Các tập tin trong thư mục gốc không được chứa bất kỳ /giá trị nào.

Một tập lệnh đơn giản tôi đã viết để giải nén các tập tin theo cách đó:

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

Chỉnh sửa: tập lệnh bây giờ cũng hoạt động với zip


Kịch bản này không hoạt động như mong đợi. Nó tạo một thư withdirmục cho kho lưu trữ withdir.zipmặc dù nó chỉ chứa một thư mục trong thư mục gốc vì grep -c "Folder = -"trả về 3.
Marco

ah, Thư mục có vẻ khác nhau đối với các tệp zip. Tôi sẽ tìm cách khắc phục
crater2150

@Marco: Tôi đã thay đổi tập lệnh và kiểm tra tập lệnh bằng các tệp zip, giờ đây nó chỉ tạo thư mục khi cần
crater2150

3

patool xử lý các loại lưu trữ khác nhau và tạo thư mục con trong trường hợp kho lưu trữ chứa nhiều tệp để tránh làm lộn xộn thư mục làm việc với các tệp được trích xuất.

Tạo kho lưu trữ

patool create archive.zip somedirectory

Trích xuất kho lưu trữ

patool extract archive.zip

Để có được một danh sách các định dạng được hỗ trợ, sử dụng patool formats.


1

Bạn cũng có thể sử dụng unar , tạo một thư mục chứa theo mặc định khi có hai hoặc nhiều tệp cấp cao nhất:

$ 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

Thêm vào -dđể luôn tạo một thư mục chứa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.