2013-06-05 27 views
14

Khi tôi sử dụng tar -xzf *.gz để trích xuất tất cả các tệp .gz trong thư mục hiện tại, tôi nhận được lỗi Not found in archive. Tuy nhiên, nó hoạt động tốt nếu tôi trích xuất từng cái một hoặc sử dụng một vòng lặp nhưLỗi 'tar: not found in archive' khi sử dụng cụm từ thông dụng

for file in `ls *.gz`; do tar -xzf $file; done 

Lý do cho lỗi này là gì?

+0

nó được gây ra bởi thực tế là cú pháp lập luận của tar chấp nhận chỉ một tar đơn trong dòng lệnh và phần còn lại được hiểu là một thứ khác. Bạn cũng có thể sử dụng xargs ('ls * .gz | xargs -n1 tar -xzf' hoặc giống nhau). – ShinTakezou

+0

tar không chấp nhận mẫu glob làm đối số (nghĩa là nó sẽ không diễn giải nó) afaik – ShinTakezou

+0

@ShinTakezou: nhưng vỏ sẽ mở rộng ký hiệu '* .gz'; 'tar' sẽ không (thường) xem' * .gz'. Đôi khi, bạn muốn trích xuất các tệp có '*' trong tên. Ví dụ: 'tar -xf abc.tar.gz 'src/prog/* name. *'' Sẽ trích xuất các tệp như 'src/prog/bigname.c',' src/prog/smallname.h'; các dấu nháy đơn ngăn cản trình bao mở rộng '*' và 'tar' thực sự mở rộng nó. –

Trả lời

16

Khi bạn viết:

tar -xf *.gz 

lệnh tar thấy (ví dụ):

tar -xf abc.tar.gz def.tar.gz ghi.tar.gz 

này được hiểu như là một yêu cầu để trích xuất def.tar.gzghi.tar.gz từ kho lưu trữ abc.tar.gz. Vì các tệp không có trong đó, bạn nhận được thông báo cảnh báo.

Nói cách khác, tar hoạt động trên một tệp tar duy nhất (có thể được nén) tại một thời điểm (trong một lần gọi). Nó không hoạt động trên nhiều tập tin tar.

Lưu ý rằng nếu abc.tar.gz chứa một tập tin pqr/xyz/important.c, bạn có thể trích xuất chỉ là một tập tin bằng cách xác định:

tar -xf abc.tar.gz pqr/xyz/important.c 

Ký hiệu bạn sử dụng chỉ là một biến thể trên ký hiệu này.

(Và có, có thể có lý do để tar một tệp tar. Ví dụ: Gmail không cho phép bạn gửi tệp tar hoặc tệp tar gzipped chứa tệp thực thi. Tuy nhiên, nếu bạn nhúng gzipped tar tập tin bên trong một tập tin tar không nén, nó không nhìn bên trong tập tin bên trong để tìm tập tin thực thi. Tôi sử dụng này khi tôi cần phải gửi một tập tin tar với một tập lệnh thực thi configure.)

18

Khi bạn viết

tar -xzf *.gz 

vỏ của bạn mở rộng nó thành chuỗi:

tar -xzf 1.gz 2.gz 3.gz 

(giả sử 1.gz, 2.gz và 3.gz nằm trong thư mục hiện tại của bạn).

tar nghĩ rằng bạn muốn trích xuất 2.gz3.gz từ 1.gz; anh ta không thể tìm thấy những tập tin này trong kho lưu trữ và gây ra thông báo lỗi.

Bạn cần sử dụng vòng lặp for của lệnh xargs để trích xuất tệp của mình.

ls *.gz |xargs -n1 tar -xzf 

Điều đó có nghĩa là: chạy cho tôi tar -xzf cho mỗi gz -file trong thư mục hiện tại.

3

lý do chính là tar lấy một đối số tên tệp duy nhất. Khi bạn đang gọi tar *.tgz, bash sẽ mở rộng * thành tất cả các tên tệp có định dạng tgz và nó trở thành tar file1 file2 file3 không được chấp nhận bởi tar.Vì vậy, hoặc là bạn sử dụng một vòng lặp for như for i in *.tgz; do tar -zxvf $i ;done hoặc sử dụng một số lệnh khác mà thực hiện tar như một tác dụng phụ như thể hiện trong các ý kiến, được ls hoặc find . -maxdepth 1 -name \*tgz -exec tar -zxvf {} \; (ls đầu ra luôn có rủi ro)

+0

Tại sao đầu ra ls luôn rủi ro? –

+0

Đầu ra từ 'ls' không rõ ràng nếu tên có khoảng trắng hoặc dòng mới. Với những cái tên không có khoảng trắng (kể cả không có dòng mới), nó vẫn ổn, nhưng bạn không thể dựa vào những cái tên không có không gian trong những ngày này. –

+0

@ Jonathan Leffler, vâng, đúng rồi! cảm ơn bạn –