membuat arsip menggunakan tar termasuk semua 'dotfiles' tetapi tidak termasuk semua subdirektori dan / wo struktur direktori

18

Saya ingin mencadangkan semua 'dotfiles' (fe .zshrc) di bawah direktori home saya dengan tar , tetapi tidak termasuk struktur direktori dan semua subdirektori.

Saya sudah mencobanya beberapa kali dengan perintah yang berbeda, tetapi yang terbaik yang saya raih adalah arsip yang menyertakan direktori tersembunyi $HOMEjuga.

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

Saya juga berpikir tentang menggunakan finddan menyalurkan hasilnya ke tar, tetapi tidak berhasil. Apakah ada yang tahu bagaimana mencapai ini - tampaknya - tugas mudah?

PS: Sebagian besar waktu ketika saya menggunakan tar untuk membuat arsip, saya harus berpikir tentang komik xkcd:

xkcd 1168 :)

klingt.net
sumber
Jawaban sim bekerja, tetapi jika seseorang mendapat regex yang hanya cocok dengan file yang disembunyikan, silakan posting itu!
klingt.net
1
Tentunya ini akan lebih baik dicapai dengan shell Anda. Saya mengerti bahwa zsh memiliki gumpalan yang hanya memilih file - *(.)- dan saya pikir itu mengecualikan .dan ..dari .*default (dan mereka tidak akan diambil oleh .*(.), karena hanya memilih file). Saya tidak menggunakan zsh sendiri, jadi saya tidak cukup yakin untuk mengubahnya menjadi jawaban.
evilsoup

Jawaban:

14

Anda dapat menggunakan perintah ini untuk membuat cadangan semua dotfile Anda ( .<something>) di $HOMEdirektori Anda :

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

regex hanya menggunakan tar?

metode # 1

Saya meneliti ini sedikit dan muncul kosong. Faktor pembatas adalah bahwa ketika tarmelakukan itu tidak termasuk, garis miring ( /) yang muncul dengan direktori bukan bagian dari persamaan ketika tar melakukan pencocokan polanya.

Ini sebuah contoh:

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

Varian ini termasuk pengecualian .*/dan Anda dapat melihat dengan saklar verbose dihidupkan ke tar -v,, bahwa direktori ini melewati pengecualian itu.

metode # 2

Saya pikir mungkin saklar --no-wildcards-match-slashatau --wildcards-match-slashakan bersantai keserakahan .*/tapi ini tidak berpengaruh juga.

Mengambil slash dari pengecualian, .*juga bukan pilihan karena itu akan memberitahu taruntuk mengecualikan semua dotfiles dan dotdirectories:

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

metode # 3 (Jelek!)

Jadi satu-satunya alternatif lain yang bisa saya bayangkan adalah menyediakan daftar file tar. Sesuatu seperti ini:

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

Pendekatan ini memiliki masalah jika jumlah file melebihi jumlah maksimum ruang untuk meneruskan argumen ke perintah akan menjadi masalah yang mencolok. Yang lain adalah bahwa itu jelek dan terlalu rumit.

jadi apa yang kita pelajari?

Tampaknya tidak ada cara yang mudah dan elegan untuk menyelesaikan ini menggunakan tar& ekspresi reguler. Jadi untuk komentar @ terdon, find ... | tar ...benar-benar cara yang lebih tepat untuk melakukan ini.

slm
sumber
Saya benar-benar ingin menyelesaikannya regex, tetapi saya seharusnya tahu bahwa itu tidak akan bekerja seperti itu :)
klingt.net
@ klingt.net - itu mungkin, saya sedang mencari sekarang.
slm
@ klingt.net mengapa Anda lebih suka cara yang lebih rumit? Menggunakan regexAnda mungkin perlu untuk melarikan diri dari titik terkemuka dan akan mengalami kesulitan mengabaikan .dan ... Saya yakin itu mungkin karena slm mungkin akan menunjukkan tetapi saya tidak melihat mengapa itu akan bermanfaat.
terdon
1
@ klingt.net - segala sesuatu yang ditemukan oleh findperintah dapat diteruskan sebagai argumen tar. The {}mengatakan di mana Anda ingin hasil yang masuk sesuai -execperintah. Kata +mengatakan untuk menambahkan sebanyak mungkin hasil findsesuai pada baris perintah dan memanggil tarhanya beberapa kali daripada setiap kali ditemukan hasil.
slm
1
@ klingt.net - tidak ada cara untuk mencapai ini menggunakan regexdan tarkarena tidak ada cara untuk mengisolasi direktori dot ( .blah/). Tar tidak menggunakan garis miring trailing saat melakukan pengecualian.
slm
4

Jenis kontrol atas file yang cocok jauh di luar zona kenyamanan tar. Aturannya untuk mencocokkan file terbatas pada kecocokan sederhana atas nama.

find adalah satu arah, tetapi karena Anda memiliki zsh, Anda membuatnya lebih mudah:

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

Bahwa .dalam tanda kurung pada akhir ekspresi wildcard adalah kualifikasi glob yang mengatakan "hanya cocok dengan file biasa".

Tautan simbolis ke file biasa tidak cocok. Jika Anda mengubahnya .*(-.), mereka akan dimasukkan, tetapi file tidak akan berakhir di arsip kecuali jika itu juga disertakan. Jika Anda ingin mengganti tautan simbolik dengan targetnya, buat itu .*(-.:A):Amenambahkan pengubah perluasan riwayat yang menyelesaikan semua tautan simbolik ke jalur yang tidak menggunakan tautan simbolik.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
3

Jawaban ini didasarkan pada slm, tetapi saya juga akan menunjukkan kepada Anda bagaimana memasukkan direktori yang dimulai dengan .

Untuk zip file dot di direktori home Anda:

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

Untuk memasukkan direktori:

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

Ini ?opsional di perintah pertama, tetapi tidak di perintah kedua, jika tidak, findakan menyertakan .direktori (saat ini).

sudoman
sumber
1

bagaimana dengan:

tar -C $HOME -cvzf dotfiles.tgz .
orang dgn nama yg tdk dikenal
sumber