Làm cách nào để buộc unzip / zip không tạo thư mục con khi tôi giải nén nó?


19

Tùy thuộc vào cách tạo tệp zip, đôi khi, nó sẽ trích xuất tất cả các tệp trực tiếp và đôi khi, nó sẽ trích xuất các tệp vào thư mục con.

Nếu điều sau là đúng, làm thế nào tôi có thể buộc unziplệnh "bỏ qua" thư mục cấp đầu tiên đó?

Thí dụ:

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

Những gì tôi nhận được là /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/

Những gì tôi muốn là về các tệp được trích xuất /tmp/omeka/, (tăng một cấp và không có số phiên bản trong cấu trúc thư mục)

/tmp/omeka/(files)

Tôi biết tôi có thể sử dụng -jtùy chọn để "đường dẫn rác" nhưng tôi muốn giữ cấu trúc thư mục con, không phải là cấu trúc thư mục cấp cao nhất. Tôi có thể làm cái này như thế nào?


ps: Tôi biết rằng tôi có thể giải nén và sau đó mvlà các tệp, nhưng tôi muốn xem liệu có cách nào để thực hiện việc này ngay từ lệnh giải nén không
cwd

Tôi không biết về một. Nhưng nếu tên tệp luôn khớp (ngoài phần mở rộng) tên thư mục, thì nó khá đơn giản để kịch bản đổi tên của thư mục được trích xuất.
Mat

3
Tôi thấy những gì bạn đang cố gắng làm, nhưng tôi sẽ không đề xuất nó. Tước số phiên bản từ các nguồn dự án của bạn là một ý tưởng tồi; bạn chỉ nên giải nén bình thường và sử dụng ln -s nếu bạn muốn một tên ngắn hơn mà không có thông tin phiên bản. Bằng cách đó, bạn luôn biết phiên bản nào bạn đang chạy và có thể dễ dàng cập nhật lên phiên bản mới bằng cách chuyển liên kết.
Burton Samograd

@BurtonSamograd - đó sẽ là lý tưởng, nhưng tôi vẫn tò mò liệu có cách nào hiệu quả để làm điều này không vì một số phần mềm, lấy Wordpress làm ví dụ, đặt mọi phiên bản trong một /wordpress/thư mục (không có số phiên bản) trong tệp zip. Nó thực sự tốt unzipvà sau đó mvnhưng không kiểm soát được điều này và phải thực hiện nó trong hai bước luôn khiến tôi lo lắng một chút. May mắn thay, Wordpress cũng có .tar.gzhương vị :)
cwd

Hãy thửcd /tmp/omeka && ln -s -T . omeka-1.5.1
James Youngman

Câu trả lời:


4

Sử dụng hệ thống tệp FUSE cho phép bạn duyệt các tài liệu lưu trữ như thư mục, chẳng hạn như AVFS . Sử dụng cpđể trích xuất các tập tin vào thư mục bạn chọn.

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

Vì chúng tôi giả định rằng có một thư mục toplevel trong kho lưu trữ, bạn có thể rút ngắn thư mục này xuống

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

@Giles bạn là chuyên gia đến và trả lời tất cả các câu hỏi mà không ai khác có thể trả lời, vì vậy tôi đoán đây thực sự là cách duy nhất để làm điều này. Tôi đã hy vọng unzipcó một số phép thuật để làm điều này, chẳng hạn như chỉ định các tệp được trích xuất như thế */*, mà tôi có thể sử dụng mà không cần cài đặt một tiện ích khác, nhưng tôi đoán là không. Cảm ơn. +1
cwd

6

Nếu tệp zip của bạn không chứa cấu trúc thư mục hoặc bạn không cần phải giữ nó, bạn có thể sử dụng tệp này:

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

3

Kịch bản này không mạnh mẽ, nhưng hoạt động trong các trường hợp đơn giản:

...
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

Nó chỉ kiểm tra xem có chính xác một thư mục con hay không, và nếu vậy, di chuyển mọi thứ ra khỏi nó sau đó xóa nó.


2

Tôi mới đăng ký hôm nay, vì vậy tôi không thể đưa ra câu trả lời @SteveBennet và không thể thêm nhận xét ở đó.

Dựa trên câu trả lời của anh ấy, tôi đã tạo ra một hàm đệ quy như thế này:

...

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"

Giống như @SteveBennet đã nói: kịch bản này không mạnh mẽ, nhưng hoạt động trong các trường hợp đơn giản.

Hy vọng nó hữu ích.


1

Cần hình như patch --strip=ntùy chọn

Sẽ là mong muốn khi có một tùy chọn như patch --strip=number(hoặc -pnumber) cắt numbercác thành phần đường dẫn lúc đầu (tham chiếu so sánh và hợp nhất các tệp: patch Directories ).

Giải pháp khác, khả năng ứng dụng

Không có điều đó, có một giải pháp khác, loại hackish nhưng hoạt động. Trong trường hợp của tôi, tôi muốn ghi đè lên một thư mục chứa đầy các tệp hiện có với nội dung của một zip, mà không cần trích xuất toàn bộ zip trước.

Khi giải pháp này hoạt động và giải pháp của @ Gilles cũng có sẵn, giải pháp sau cũng sẽ hoạt động. Tuy nhiên, giải pháp này không yêu cầu có sẵn hệ thống tập tin FUSE.

Làm thế nào để làm nó

Giả sử bạn biết thư mục bổ sung, trong trường hợp của omeka-1.5.1bạn, bạn có thể làm điều này:

mkdir omeka
ln -s . omeka/omeka-1.5.1 # create a symlink that redirects output
unzip omeka-1.5.1.zip -d omeka/
rm omeka/omeka-1.5.1 # remote symlink

unzipsẽ cố gắng giải nén omeka-1.5.1mà thực sự là một liên kết tượng trưng để chứa dir. Kết quả là, các tập tin sẽ hạ cánh omekatrực tiếp.

Các biến thể có thể

Bạn có thể tưởng tượng các biến thể để chuyển hướng một hoặc nhiều phần của hệ thống phân cấp.

ln -s ../myfoo omeka/omeka-1.5.1/foo
ln -s ../../mybarxyzzy omeka/omeka-1.5.1/subdir/bar

Phần kết luận

Giải pháp này có phần cụ thể, nhưng nó có các trường hợp sử dụng và tôi chỉ tình cờ sử dụng nó.


Giải pháp tuyệt vời nếu bạn biết đường dẫn!
grepsedawk

Đường dẫn có thể được thăm dò bằng cách liệt kê nội dung zip trước, ví dụ như với unzip -l. Điều này thậm chí có thể được tự động bằng cách sử dụng một tập lệnh chỉ ra một phần của đường dẫn phổ biến.
Stéphane Gourmetichon

Ồ hoàn toàn, nó chỉ là một tấn dễ dàng hơn nếu bạn biết đường dẫn. Tôi đã chơi với unzip -l một chút nhưng nó hơi grep / sed / awk hơn tôi dự định nên tôi đã rút lui.
grepsedawk

zipinfo -1có thể là một khởi đầu tốt Trường hợp sử dụng của bạn là gì?
Stéphane Gourichon

github.com/grepsedawk/wow-config/blob/, trong trường hợp này, tôi biết thư mục :)
grepsedawk

1

Nhiều khả năng bạn muốn chạy unzipvới -jtùy chọn, như trong:

unzip -j files.zip -d ./output/

Nhưng bạn có thể ngạc nhiên bởi hành vi của nó:

-j đường dẫn rác. Cấu trúc thư mục của kho lưu trữ không được tạo lại; tất cả các tệp được gửi trong thư mục giải nén (theo mặc định, tệp hiện tại).

Nếu bạn trích xuất files.ziptrong thư mục đầu ra ./outputvà kết quả là:

./output/files/subfolder1/f1
./output/files/subfolder1/f2

sau đó -jtùy chọn sẽ cung cấp cho bạn cái này (tất cả các đường dẫn sọc):

./output/f1
./output/f2
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.