tạo kho lưu trữ bằng tar bao gồm tất cả 'dotfiles' nhưng loại trừ tất cả các thư mục con và cấu trúc thư mục / wo


18

Tôi muốn sao lưu tất cả các 'dotfiles' .zshrctrong thư mục chính của mình bằng tar , nhưng không bao gồm cấu trúc thư mục và tất cả các thư mục con.

Tôi đã thử nó nhiều lần với các lệnh khác nhau, nhưng điều tốt nhất tôi đạt được là một kho lưu trữ bao gồm cả các thư mục ẩn bên dưới $HOME.

#!/bin/zsh
BACKUPFILE=dotfile_backup.tar.gz
tar --create --file=$HOME/$BACKUPFILE --auto-compress --no-recursion --exclude=. --exclude=.. --exclude=*/ --directory=$HOME .*

Tôi cũng đã nghĩ về việc sử dụng findvà dẫn kết quả đến tar, nhưng không có may mắn. Có ai biết làm thế nào để đạt được điều này - có vẻ dễ dàng - nhiệm vụ?

PS: Hầu hết khi tôi sử dụng tar để tạo một kho lưu trữ, tôi phải nghĩ về truyện tranh xkcd:

xkcd 1168 :)


Câu trả lời của sim hoạt động, nhưng nếu ai đó có regex chỉ khớp với các tệp bị ẩn, vui lòng gửi nó!
klingt.net

1
Chắc chắn điều này sẽ đạt được tốt hơn với vỏ của bạn. Tôi hiểu zsh có những đống mà chỉ chọn file - *(.)- và tôi nghĩ rằng nó không bao gồm ...từ .*theo mặc định (và họ sẽ không được nhặt bởi .*(.)dù sao, vì nó lựa chọn duy nhất tập tin). Tôi không sử dụng zsh cho mình, vì vậy tôi không chắc chắn để biến điều này thành một câu trả lời.
evilsoup

Câu trả lời:


14

Bạn có thể sử dụng lệnh này để sao lưu tất cả các dotfiles ( .<something>) trong $HOMEthư mục của mình :

$ cd ~
$ find . -maxdepth 1 -type f -name ".*" -exec tar zcvf dotfiles.tar.gz {} +

regex chỉ sử dụng tar?

phương pháp số 1

Tôi đã nghiên cứu điều này khá nhiều và đến trống rỗng. Yếu tố giới hạn sẽ là khi tarthực hiện nó không bao gồm, dấu gạch chéo ( /) hiển thị với các thư mục không phải là một phần của phương trình khi tar thực hiện khớp mẫu.

Đây là một ví dụ:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*/'} .*
.qalculate/
.qt/
.qterm/
.qtoctave/
.RapidSVN
.RData
.Rhistory

Biến thể này bao gồm một loại trừ .*/và bạn có thể thấy với công tắc dài dòng được bật thành tar -v, rằng các thư mục này đang đi qua loại trừ đó.

phương pháp số 2

Tôi nghĩ có lẽ các công tắc --no-wildcards-match-slashhoặc --wildcards-match-slashsẽ làm giảm sự tham lam của .*/nhưng điều này cũng không có tác dụng.

Lấy dấu gạch chéo ra khỏi loại trừ, .*không phải là một tùy chọn vì điều đó sẽ nói tarđể loại trừ tất cả các dotfiles và dotdirectories:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*'} .*
$

phương pháp số 3 (Xấu xí!)

Vì vậy, cách khác duy nhất tôi có thể hình dung là cung cấp một danh sách các tập tin tar. Một cái gì đó như thế này:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --wildcards-match-slash --exclude={'.','..','.*/'} $(ls -aF | grep -E "^\..*[^/]$")
.RapidSVN
.RData
.Rhistory

Cách tiếp cận này có vấn đề nếu số lượng tệp vượt quá dung lượng tối đa để truyền đối số cho lệnh sẽ là một vấn đề rõ ràng. Khác là nó xấu và quá phức tạp.

Vì vậy, chúng tôi đã học được những gì?

Dường như không phải là một cách đơn giản và thanh lịch để hoàn thành việc này bằng cách sử dụng tarcác biểu thức thông thường. Vì vậy, theo nhận xét của @ terdon, find ... | tar ...thực sự là cách thích hợp hơn để làm điều này.


Tôi thực sự muốn hoàn thành nó regex, nhưng tôi nên biết rằng nó sẽ không hoạt động theo cách đó :)
klingt.net

@ klingt.net - điều đó là có thể, tôi đang tìm kiếm ngay bây giờ.
slm

@ klingt.net tại sao bạn thích cách phức tạp hơn? Sử dụng regexbạn có thể sẽ cần phải thoát khỏi dấu chấm hàng đầu và sẽ gặp khó khăn khi bỏ qua .... Tôi chắc chắn điều đó là có thể vì slm có thể sẽ chứng minh nhưng tôi không hiểu tại sao nó lại đáng giá.
terdon

1
@ klingt.net - mọi thứ mà findlệnh tìm thấy được chuyển qua làm đối số tar. Nó {}nói nơi bạn muốn những kết quả đó đi trong -execlệnh tương ứng . Việc +nói thêm nhiều kết quả findnhư sẽ phù hợp với dòng lệnh và tarchỉ gọi một vài lần thay vì mỗi lần tìm thấy kết quả.
slm

1
@ klingt.net - không có cách nào để thực hiện việc này bằng cách sử dụng regextarbởi vì không có cách nào để cô lập các thư mục dấu chấm ( .blah/). Tar không sử dụng dấu gạch chéo khi thực hiện loại trừ.
slm

4

Loại kiểm soát đối với các tệp phù hợp nằm ngoài vùng thoải mái của tar. Quy tắc của nó cho các tệp phù hợp được giới hạn ở các kết quả khớp đơn giản trên các tên.

find là một cách, nhưng vì bạn có zsh, bạn có nó dễ dàng hơn:

tar -cf "$HOME/$BACKUPFILE" --auto-compress .*(.)

Rằng .trong ngoặc đơn ở cuối biểu thức ký tự đại diện là một vòng loại toàn cầu nói rằng chỉ phù hợp với các tệp thông thường.

Liên kết tượng trưng đến các tập tin thông thường không phù hợp. Nếu bạn đổi thành .*(-.), chúng sẽ được bao gồm, nhưng tệp sẽ không nằm trong kho lưu trữ trừ khi nó cũng được bao gồm. Nếu bạn muốn thay thế liên kết tượng trưng bằng các mục tiêu của chúng, hãy thực hiện điều đó .*(-.:A):Athêm công cụ sửa đổi mở rộng lịch sử giải quyết tất cả các liên kết tượng trưng vào một đường dẫn không sử dụng liên kết tượng trưng.


3

Câu trả lời này dựa trên slm, nhưng tôi cũng sẽ chỉ cho bạn cách bao gồm các thư mục bắt đầu bằng .

Để nén các tập tin dấu chấm trong thư mục nhà của bạn:

$ cd
$ find . -maxdepth 1 -type f -name ".?*" -exec tar czfv dotfiles.tgz {} +

Để bao gồm các thư mục:

$ find . -maxdepth 1 -name ".?*" -exec tar czfv dotfiles.tgz {} +

Các ?là tùy chọn trong lệnh đầu tiên, nhưng không phải trong thứ hai, nếu không, findsẽ bao gồm các .thư mục (hiện hành).


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.