trích xuất tar vào thư mục có cùng tên cơ sở?


18

Tôi có một tập tin nén như thế myArchive123.tar.gz. Bên trong nó chứa một thư mục nhưhelloWorld

Nếu tôi giải nén nó: tar -xf myArchive123.tar.gztôi nhận được helloWorldthư mục:

ls 
myArchive123.tar.gz
helloWorld 

Tôi muốn đầu ra có cùng tên với tên tệp trừ phần mở rộng .tar.gz. I E:

tar <magic paramaters> myArchive123.tar.gz 
ls 
 myArchive123.tar.gz
 myArchive123
cd myArchive123
ls 
  helloWorld

Điều này có thể được thực hiện?

  • Tôi không bao giờ biết những gì bên trong kho lưu trữ. Có thể là một thư mục, có thể là nhiều tập tin.
  • Tôi sẽ ổn khi sử dụng một công cụ khác nếu tar không thể làm được.
  • Tôi sẽ ổn với một hình thức dài hơn có thể được chuyển thành một kịch bản

EDIT
Trong thời gian đó, tôi đã hack cho mình một kịch bản dường như hoàn thành công việc. (xem câu trả lời được đăng của tôi dưới đây). Nếu nó có thể được cải thiện, xin vui lòng gửi bình luận / câu trả lời bổ sung. Điều chính là nó nên được đóng gói thành một lớp lót như:

extract <file>

1
Có phải kho lưu trữ luôn chứa chính xác một thư mục?
Đánh dấu Plotnick


Tôi không biết những gì bên trong nó tại thời điểm khai thác. Điều này không nên phụ thuộc vào những gì bên trong kho lưu trữ. Nếu đó là một thư mục, giải nén thư mục trong đó. nếu đó là một tập tin, giải nén tất cả các tập tin.
Leo Ufimtsev

Trong thời gian đó, tôi đã viết một kịch bản (xem bên dưới). Tôi có thể chấp nhận câu trả lời chỉ trong 2 ngày.
Leo Ufimtsev

Lưu trữ sẽ bao giờ chứa nhiều hơn một thư mục ở cấp cao nhất?
Đánh dấu Plotnick

Câu trả lời:


10

Với gnu tar, bạn có thể sử dụng --xform(hoặc --transform) để thêm vào /prefix/từng tên tệp:

tar -xf myArchive.tar.gz --xform='s|^|myArchive/|S'

lưu ý rằng không có bất hàng đầu /trong prefix/sedbiểu hiện đầu với Sloại trừ mục tiêu liên kết tượng trưng từ biến đổi tên tập tin.
Để kiểm tra nó (chạy khô):

tar -tf myArchive.tar.gz --xform='s|^|myArchive/|S' --verbose --show-transformed-names

Để giúp bạn bắt đầu, đây là một kịch bản rất đơn giản mà bạn có thể gọi là extract <file>:

STRIP = $ {1%. *} #Strip hậu tố cuối cùng
NAME = $ {STRIP% .tar} #strip .tar hậu tố, nếu có
tar -xf "$ 1" --xform = "s | ^ | $ NAME / | S" #run lệnh

Điều này gần với những gì tôi muốn, ngoại trừ việc tôi muốn có thể gói nó thành một cái gì đó như: giải nén <file>
Leo Ufimtsev

Đây là lỗi, nó dừng lại ở dấu chấm đầu tiên. Ví dụ: tôi có một tệp như thế này: eclipse-SDK-4.5M6-linux-gtk-x86_64.tar.gz Tôi mong đợi một đầu ra mà không có .tar.gz, nhưng tôi nhận được nhật thực-sdk-4
Leo Ufimtsev

Trong đoạn script trên, tôi loại bỏ phần mở rộng và tước nó thêm nếu tôi tìm thấy một 'tar'.
Leo Ufimtsev

Nói chung, với nhiều loại tài liệu lưu trữ. Tôi đã hy vọng cho một lớp lót nhanh chóng, tôi nghĩ có lẽ tôi đang thiếu một số cờ đối số. Nhưng dường như không có giải pháp tầm thường nào cho việc này?
Leo Ufimtsev

Đồ tốt. Điều này hoạt động và ngắn hơn so với kịch bản tôi đã viết. Tốt đẹp!
Leo Ufimtsev

7

Vâng, bạn có thể làm điều đó trong một vài bước ít nhất. Nếu bạn đã làm

mkdir <archive name>
tar -xf <archive name>.tar.gz --strip-components=1 -C <archive name>

điều đó sẽ hoàn thành nhiệm vụ, mặc dù có thể có một câu trả lời nhỏ gọn hơn ngoài kia.


3

Chỉnh sửa

Câu trả lời được chấp nhận ngắn hơn dưới đây. (làm điều tương tự, nhưng ngắn hơn thường tốt hơn).


Cuối cùng tôi đã hack cho mình một kịch bản cho nhiệm vụ trong tay. nó hoạt động với .tar .tar.gz và .gz

#!/bin/sh
#usage:
# nameOfScript myArchive.tar.gz
# nameOfScript myArchive.gz
# nameOfScript myArchive.tar
#
# Result:
# myArchive   //folder
fileName="${1%.*}" #extracted filename

#handle the case of archive.tar.gz
trailingExtension="${fileName##*.}"
if [ "$trailingExtension" == "tar" ]  
then
    fileName="${fileName%.*}"  #remove trailing  tar.
fi

mkdir "$fileName"
tar -xf "$1" --strip-components=0 -C "$fileName"

Sử dụng:

   nameOfScript archive.tar.gz 
   ls 
    archive
   cd archive 
   ls 
    <archive content>

Lưu ý, giải pháp này có khả năng chấm trong tên tệp. Ví dụ: Eclipse-4.5M-SDK.tar.gz.

Tôi giữ kịch bản trong repo git của tôi. Để biết phiên bản mới nhất, hãy xem: https://github.com/LeoUfimtsev/ldts/blob/master/pathscripts/leo-tar-here


2

Một giải pháp khả thi hơn là sử dụng --transformtùy chọn:

tar -xzf ARCHIVE_NAME.tgz --transform="s/OLD_DIR_NAME/ARCHIVE_NAME/"

Với các tập tin của bạn:

tar -xzf myArchive123.tar.gz --transform="s/helloWorld/myArchive123/"

1
nhưng điều này giả sử rằng bạn biết những gì bên trong kho lưu trữ
Leo Ufimtsev

ví dụ: làm thế nào tôi có thể biến tập lệnh này thành tập lệnh một dòng mà không biết những gì bên trong kho lưu trữ?
Leo Ufimtsev

Bạn hoàn toàn đúng. Đó chỉ là một giải pháp khả thi khi tôi viết ở đây ...
svq

có sự khác biệt nào giữa điều đó và --strip-compoments = 0 myArchive123 không?
Leo Ufimtsev

1
--strip-components=0chỉ cần xóa tên thư mục đầu tiên khỏi đường dẫn và với -Ctùy chọn lưu các tệp đã lưu trữ vào thư mục mới.
svq
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.