Cách chọn tên thư mục trong quá trình gỡ lỗi


125

Nói rằng tôi có tập tin được đặt tên ugly_name.tar, mà khi giải nén, trở thành ugly_namethư mục. Lệnh nào tôi có thể sử dụng sao cho tên thư mục kết quả pretty_namethay thế?

Câu trả lời:


172

Điều này sẽ làm việc:

mkdir pretty_name && tar xf ugly_name.tar -C pretty_name --strip-components 1

-Cthay đổi thư mục được chỉ định trước khi giải nén (hoặc đóng gói). --strip-componentsxóa số lượng thư mục được chỉ định khỏi tên tệp được lưu trữ trong kho lưu trữ.

Lưu ý rằng điều này không thực sự di động. GNU tar và ít nhất một số tars BSD có --strip-componentstùy chọn, nhưng dường như không tồn tại trên các nền tảng giống như unix khác.

Cách làm việc ngu ngốc này sẽ làm việc khá nhiều ở mọi nơi.

tar xf ugly_name.tar && mv ugly_name pretty_name

Tôi nghĩ rằng tôi sẽ gắn bó với phiên bản câm :)
phunehehe

28
@phunehehe: một ưu điểm của phiên bản thông minh là bạn không cần phải biết trước tên thư mục chưa được xác thực là gì
tshepang

2
Tôi có thể thêm, rằng cái này hoạt động nhiều hơn "Pretty_name". Bạn cũng có thể mở ra một thư mục cụ thể theo cách này. Ví dụ:tar -xvf /tmp/backupfiles.tar -C /var/www/
Tướng Redneck

2
Tôi thường sử dụng cách ngu ngốc và tôi sử dụng các ký tự đại diện trong trường hợp tôi không biết tên xấu xí sẽ là gì hoặc tôi không muốn viết nó ra. mv ugly-* pretty_name
David Grayson

1
Cách ngu ngốc không hoạt động nếu đã có một ugly_namethư mục. Nhân tiện, vẻ đẹp là trong mắt của kẻ si tình.
kmiklas

30

Với GNU tar .161.16, sử dụng --transformđể áp dụng chuyển đổi reg reg sed cho mỗi tên tệp (phép chuyển đổi được áp dụng trên đường dẫn đầy đủ trong kho lưu trữ):

tar xf foo.tar --transform 's!^ugly_name\($\|/\)!pretty_name\1!'

Nếu ugly_namelà thành phần toplevel của tất cả các tên tệp trong kho lưu trữ, bạn không cần bận tâm đến việc khớp chính xác:

tar xf foo.tar --transform 's/ugly_name/pretty_name/'

Nếu bạn không biết tên của thư mục toplevel, bạn vẫn có thể sử dụng phương pháp này, mặc dù bạn có thể thích --strip-componentsthay thế.

tar xf foo.tar --transform 's!^[^/]\+\($\|/\)!pretty_name\1!'

Với pax, tiện ích lưu trữ POSIX, sử dụng -stùy chọn, lấy biểu thức thay thế giống như sed làm đối số.

pax -rf foo.tar -s '!^ugly_name\($\|/\)!pretty_name\1!'
pax -rf foo.tar -s '/ugly_name/pretty_name/'
pax -rf foo.tar -s '!^[^/]\+\($\|/\)!pretty_name\1!'

9

Dùng cái này :

tar -xvf ugly_name.tar
mv ugly_name pretty_name

9
Bạn có thể thích sử dụng &&toán tử danh sách giữa hai lệnh đó, vì vậy lệnh thứ hai chỉ được thực hiện nếu lệnh thứ nhất thành công.
thao tác

1
Điều này có thể có hậu quả không mong muốn nếu một thư mục ugly_nameđã tồn tại.
Drew Dormann

7

Cách đơn giản nhất

tar xvf dml/ugly_name.tar --one-top-level=pretty_name --strip-components 1

(1) Đây rõ ràng là không phải là cách đơn giản nhất, như smac89 đăng một câu trả lời có tính năng --one-top-level=pretty_namekhông --strip-components 1. (2) Ngược lại, câu trả lời được chấp nhận (đăng bởi Mat) tính năng --strip-components 1mà không cần --one-top-level=pretty_name. (3) Bạn có thể giải thích tại sao câu trả lời của bạn, kết hợp các tùy chọn này, tốt hơn bất kỳ câu hỏi nào không? Xin vui lòng không trả lời trong các ý kiến; chỉnh sửa  câu trả lời của bạn để làm cho nó rõ ràng và đầy đủ hơn.
G-Man

có thể là một ví dụ thực tế có thể giúp bạn làm sáng tỏ: `wget dev.mysql.com/get/Downloads/MySQL-5.7/... tar xvf mysql-5.7.23-linux-glibc2.12-x86_64.tar.gz --one-top -level = mysql57 --strip-thành phần 1 `
marquicus

Câu trả lời này là thanh lịch hơn so với câu trả lời nhiều nhất .
KaiserKatze

@ G-Man --strip-component 1là bắt buộc, với phương thức mkdirhoặc --strip-components 1phương thức, nếu không bạn chỉ cần lấy pretty_name/ugly_name/.
davidA

Đây thực sự là cách đơn giản nhất
smac89

2

Từ AskUbfox, câu trả lời này có hiệu quả với tôi:

tar zxvf ugly_name.tgz --one-top-level=pretty_name

`--one-top-level [= dir] '

Nói với tar để tạo một thư mục mới bên dưới thư mục trích xuất (hoặc thư mục được truyền cho `-C ') và sử dụng nó để bảo vệ chống lại tarbomb. Trong trường hợp không có đối số dir, tên của thư mục mới sẽ bằng với tên cơ sở của kho lưu trữ (tên tệp trừ đi hậu tố lưu trữ, nếu được công nhận). Bất kỳ tên thành viên nào không bắt đầu bằng tên thư mục đó (sau khi chuyển đổi từ `--transform 'và` --strip-thành phần') sẽ được thêm tiền tố vào nó. Các hậu tố tên tệp được nhận dạng là `.tar 'và bất kỳ hậu tố nén nào có thể nhận ra bằng See -auto-compression .


Cập nhật

Như đã chỉ ra trong các bình luận , phương pháp này không hoạt động đối với các tài liệu lưu trữ được hình thành đúng cách, tuy nhiên như một câu trả lời khác cho thấy, bạn nên thêm --strip-components 1để điều này thực sự hiệu quả. Tôi đã thử nghiệm với tùy chọn mới này và nó hoạt động cả cho các tài liệu lưu trữ có tên cấp cao nhất và không có tên cấp cao.


Vấn đề với điều này là nó không đổi tên thư mục cấp cao nhất, thay vào đó nó tạo ra một cấp độ mới, được đặt tên pretty_name, với thư mục cấp cao nhất ban đầu bên trong đó. Ví dụ: nếu tar xzf ugly_name.tgzsẽ tạo một thư mục được gọi ugly_name/, thì lệnh bạn đã cung cấp sẽ tạo pretty_name/ugly_name/.
davidA

1
@davidA Điểm tốt. Tôi đã cập nhật câu trả lời của mình để bao gồm một bản sửa lỗi cho điều này
smac89
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.