creando un archivio usando tar compresi tutti i 'dotfile' ma escludendo tutte le sottodirectory e la struttura di directory / wo


18

Voglio fare il backup di tutti i 'dotfile' (fe .zshrc) nella mia directory home con tar , ma escludendo la struttura delle directory e tutte le sottodirectory.

L'ho provato più volte con comandi diversi, ma il migliore che ho ottenuto è stato un archivio che includeva anche le directory nascoste $HOME.

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

Ho anche pensato di utilizzare finde convogliare il risultato su tar, ma senza fortuna. Qualcuno sa come realizzare questo - apparentemente facile - compito?

PS: Il più delle volte quando sto usando tar per creare un archivio, devo pensare al fumetto di xkcd:

xkcd 1168 :)


La risposta di sim funziona, ma se qualcuno ha una regex che corrisponde solo ai file nascosti, si prega di pubblicarlo!
klingt.net,

1
Sicuramente questo sarebbe meglio realizzato con la tua shell. Capisco che zsh ha gocce che selezionano solo i file - *(.)- e penso che esclude .e ..da .*di default (e non sarebbero stati raccolti da .*(.)in ogni caso, dal momento che seleziona solo i file). Non uso zsh da solo, quindi non sono abbastanza sicuro da trasformarlo in una risposta.
evilsoup,

Risposte:


14

È possibile utilizzare questo comando per eseguire il backup di tutti i dotfile ( .<something>) nella $HOMEdirectory:

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

regex usando solo tar?

metodo n. 1

Ho studiato un po 'questo e sono risultato vuoto. Il fattore limitante sarebbe che quando tarsi esegue si esclude, la barra finale ( /) che si presenta con le directory non fa parte dell'equazione quando tar sta eseguendo la sua corrispondenza del modello.

Ecco un esempio:

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

Questa variante include un'esclusione di .*/e puoi vedere con l'interruttore dettagliato attivato su tar -v, che queste directory stanno attraversando quell'esclusione.

metodo n. 2

Ho pensato che forse gli interruttori --no-wildcards-match-slasho --wildcards-match-slashavrebbero rilassato l'avidità del .*/ma questo non ha avuto alcun effetto.

Eliminare la barra dall'esclusione , .*non era neanche un'opzione poiché ciò avrebbe detto tardi escludere tutti i dotfile e dotdirectories:

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

metodo # 3 (Brutto!)

Quindi l'unica altra alternativa che posso concepire è quella di fornire un elenco di file tar. Qualcosa come questo:

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

Questo approccio ha problemi se il numero di file supera la quantità massima di spazio per passare argomenti a un comando sarebbe un problema evidente. L'altro è che è brutto e troppo complesso.

quindi cosa abbiamo imparato?

Non sembra esserci un modo semplice ed elegante per realizzare questo usando tarespressioni regolari. Per quanto riguarda il commento di @ Terdon, find ... | tar ...è davvero il modo più appropriato per farlo.


Volevo davvero farlo regex, ma avrei dovuto sapere che non funzionerà in questo modo :)
klingt.net

@ klingt.net - dovrebbe essere possibile, sto cercando ora.
slm

@ klingt.net perché preferiresti il ​​modo più complicato? Il regextuo utilizzo probabilmente avrà bisogno di sfuggire al punto iniziale e avrà difficoltà a ignorare .e ... Sono sicuro che è possibile, come dimostrerà probabilmente slm, ma non vedo perché ne varrebbe la pena.
terdon

1
@ klingt.net - tutto ciò che findtrova il comando viene passato come argomento a tar. Il {}dice dove vuoi che quei risultati vadano nel -execcomando corrispondente . Il +dice di aggiungere tanti risultati findquanti ne rientrano nella riga di comando e chiamare tarsolo un paio di volte anziché ogni volta che viene trovato un risultato.
slm

1
@ klingt.net - non c'è modo di farlo usando regexe tarperché non c'è modo di isolare le directory dei punti ( .blah/). Tar non usa la barra finale quando fa l'esclusione.
slm

4

Questo tipo di controllo sui file corrispondenti è al di fuori della zona di comfort di tar. Le sue regole per la corrispondenza dei file sono limitate a corrispondenze semplici sui nomi.

find è un modo, ma poiché hai zsh, hai più facile:

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

Quello .tra parentesi alla fine dell'espressione con caratteri jolly è un qualificatore glob che dice "abbina solo i file regolari".

I collegamenti simbolici a file normali non vengono abbinati. Se cambi a .*(-.), saranno inclusi, ma il file non finirà nell'archivio a meno che non sia anche incluso. Se vuoi sostituire il link simbolico con i loro target, crealo .*(-.:A):Aaggiunge il modificatore di espansione della cronologia che risolve tutti i link simbolici in un percorso che non utilizza link simbolici.


3

Questa risposta si basa su slm's, ma ti mostrerò anche come includere le directory a partire da .

Per comprimere i file di punti nella tua home directory:

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

Per includere le directory:

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

L' ?opzione è facoltativa nel primo comando, ma non nel secondo, altrimenti findincluderà la .directory (corrente).


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.