Chuyển đổi đường dẫn của kho lưu trữ tar mà không giải nén nó


10

GNU tar(1)có một tùy chọn gọn gàng được gọi là --transform. Từ trang người đàn ông:

--transform, --xform EXPRESSION
sử dụng sed thay thế EXPRESSION để chuyển đổi tên tệp

Điều này cho phép chuyển đổi tên đường dẫn một cách nhanh chóng khi kho lưu trữ đang được trích xuất để bạn có thể kiểm soát vị trí và cách thức trích xuất nó.

Câu hỏi của tôi là, có cách nào để thực hiện một chuyển đổi tương tự tại chỗ ; tức là không trích xuất kho lưu trữ?

Thí dụ

[user@host]$ tar tf test.tar
./foo/blah  ./foo/bleh
[user@host]$ some_deep_magic 's/foo/bar/' test.tar
[user@host]$ tar tf test.tar
./bar/blah  ./bar/bleh

Ca sử dụng

Tôi đang phân phối một tarkho lưu trữ cho những người dùng cuối cơ bản không biết gì và muốn nó trích xuất vào đúng đường dẫn mà không bị tôi can thiệp. Tôi đang cố gắng tránh các giải pháp tầm thường trong việc trích xuất kho lưu trữ, đổi tên các thư mục và đóng gói lại vì kho lưu trữ rất lớn.


Tại sao bạn không chuyển đổi tên khi tạo nó?
Jose Luis Martin

@JoseLuisMartin Phải. Trường hợp sử dụng của tôi là kho lưu trữ đã có sẵn và như tôi đã nói, tôi muốn tránh việc giải nén, chuyển đổi và đóng gói lại.
Joseph R.

1
Bạn có thể thay đổi luồng tar mà không thực sự giải nén nó vào đĩa: github.com/mafintosh/tar-stream#modifying-existing-tarballs , perldoc.perl.org/5.10.1/Archive/Tar.html , vv
vladr

Câu trả lời:


3

Bạn có thể gắn kết kho lưu trữ với archivemount hoặc mountavfs và tạo lại nó

archivemount tarfile.tar /mnt
cd /mnt
tar cf /tmp/tarfile.tar --transform 's/foo/bar/' .

hoạt động ghi trên hệ thống tệp lưu trữ sẽ hoàn thành việc viết lại đầy đủ trên umount, vì vậy dường như không phải là một lựa chọn tốt cho các tệp lớn.

BIÊN TẬP

Tôi không biết chi tiết triển khai nhưng có vẻ như chúng tôi đang lưu các tệp ghi vào bước hệ thống tệp.

Chỉ cần kiểm tra để giải quyết các anh chàng, (trên một tar của tôi / usr)

#!/bin/bash

# try to avoid slab cache issues 
cat /tmp/usr.tar > /dev/null

T="$(date +%s)"
tar xf /tmp/usr.tar
tar cf usr.tar usr --transform 's/usr/foo/'
T="$(($(date +%s)-T))"
echo "Tar/Untar seconds: ${T}"

T="$(date +%s)"
archivemount -o readonly -o nobackup /tmp/usr.tar /mnt
tar cf usr.tar /mnt  --transform 's/usr/foo/'
umount /mnt
T="$(($(date +%s)-T))"
echo "Archivemount seconds: ${T}"

T="$(date +%s)"
mountavfs
cd '/root/.avfs/tmp/usr.tar#'
tar cf /tmp/test/usr.tar   --transform 's/usr/foo/' .
T="$(($(date +%s)-T))"
echo "Avfs seconds: ${T}"

Đầu ra:

Tar/Untar seconds: 480
Archivemount seconds:  failure, a lot of read errors.
Avfs seconds: 217

Vì vậy, Avfs chiến thắng! .


1
+1 Lệnh mới thú vị. Nhưng cách tiếp cận này khác với việc giải nén kho lưu trữ như thế nào? Tôi không nói về việc thực hiện, nhưng khôn ngoan về hiệu suất.
Joseph R.
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.