Erstellen eines Archivs unter Verwendung von tar einschließlich aller 'Punktedateien', jedoch ausschließlich aller Unterverzeichnisse und der Verzeichnisstruktur / wo

18

Ich möchte alle 'dotfiles' (zB .zshrc) in meinem Home-Verzeichnis mit tar sichern , jedoch ohne die Verzeichnisstruktur und alle Unterverzeichnisse.

Ich habe es mehrmals mit verschiedenen Befehlen versucht, aber das Beste, was ich erreicht habe, war ein Archiv, das auch die versteckten Verzeichnisse darunter enthielt $HOME.

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

Ich habe auch darüber nachgedacht, finddas Ergebnis zu Teer zu leiten, aber ohne Glück. Weiß jemand, wie man diese scheinbar einfache Aufgabe löst?

PS: Die meiste Zeit, wenn ich mit tar ein Archiv erstelle, muss ich über xkcd comic nachdenken:

xkcd 1168 :)

klingt.net
quelle
Die Antwort von sim funktioniert, aber wenn jemand einen regulären Ausdruck hat, der nur mit den versteckten Dateien übereinstimmt, posten Sie ihn bitte!
klingt.net
1
Sicherlich wäre dies mit Ihrer Muschel besser zu erreichen. Ich verstehe , dass zsh hat Kleckse , die nur Dateien auswählen - *(.)- und ich denke , es schließt .und ..von .*der Standardeinstellung (und sie würden nicht abgeholt werden .*(.)sowieso, da sie nur Dateien auswählt). Ich selbst benutze zsh nicht, daher bin ich mir nicht sicher genug, um daraus eine Antwort zu machen.
Übelsuppe

Antworten:

14

Mit diesem Befehl können Sie alle Ihre dotfiles ( .<something>) in Ihrem $HOMEVerzeichnis sichern :

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

Regex mit nur Teer?

Methode 1

Ich habe das ein bisschen recherchiert und bin leer ausgegangen. Der einschränkende Faktor wäre, dass tarder abschließende Schrägstrich ( /), der bei Verzeichnissen angezeigt wird, nicht Teil der Gleichung ist, wenn tar seine Musterübereinstimmung ausführt.

Hier ist ein Beispiel:

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

Diese Variante enthält einen Ausschluss von .*/und Sie können bei eingeschaltetem Verbose-Schalter für tar sehen -v, dass diese Verzeichnisse diesen Ausschluss durchlaufen.

Methode # 2

Ich dachte vielleicht, die Schalter würden die Gier der lindern --no-wildcards-match-slashoder aber dies hatte auch keine Auswirkung.--wildcards-match-slash.*/

Das Entfernen des Schrägstrichs aus dem Ausschluss .*war auch keine Option, da dies tarzum Ausschließen aller Punktdateien und Punktverzeichnisse führen würde:

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

Methode 3 (hässlich!)

Die einzige Alternative, die ich mir vorstellen kann, ist die Bereitstellung einer Liste von Dateien tar. Etwas wie das:

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

Dieser Ansatz weist Probleme auf, wenn die Anzahl der Dateien den maximalen Speicherplatz für die Übergabe von Argumenten an einen Befehl überschreitet. Das andere ist, dass es hässlich und zu komplex ist.

Also, was haben wir gelernt?

Es scheint keinen direkten und eleganten Weg zu geben, um dies mit tar& regulären Ausdrücken zu erreichen. Um @ terdons Kommentar zu kommentieren, find ... | tar ...ist dies in der Tat der geeignetere Weg.

slm
quelle
Ich wollte es wirklich schaffen regex, aber ich hätte
wissen
@ klingt.net - es sollte möglich sein, ich suche jetzt.
SLM
@ klingt.net warum würdest du den komplizierteren Weg bevorzugen? Wenn regexSie verwenden, müssen Sie wahrscheinlich den führenden Punkt verlassen und haben Probleme, .und zu ignorieren ... Ich bin mir sicher, dass es möglich ist, wie slm wahrscheinlich zeigen wird, aber ich verstehe nicht, warum es sich lohnen würde.
Terdon
1
@ klingt.net - Alles, was der findBefehl findet, wird als Argument an übergeben tar. Die {}sagt, wo Sie diese Ergebnisse in den entsprechenden -execBefehl gehen möchten . Der Befehl +fügt so viele Ergebnisse hinzu, findwie in die Befehlszeile passen, und ruft tarnur ein paar Mal auf, anstatt jedes Mal, wenn ein Ergebnis gefunden wird.
SLM
1
@ klingt.net - es gibt keine Möglichkeit, dies mit regexund zu erreichen, tarda es keine Möglichkeit gibt, die Punktverzeichnisse ( .blah/) zu isolieren . Tar verwendet den abschließenden Schrägstrich beim Ausschließen nicht.
SLM
4

Diese Art der Kontrolle über übereinstimmende Dateien liegt weit außerhalb der Komfortzone von tar. Die Regeln zum Abgleichen von Dateien beschränken sich auf einfache Übereinstimmungen mit Namen.

find ist eine Möglichkeit, aber da Sie zsh haben, haben Sie es einfacher:

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

Die Angabe .in Klammern am Ende des Platzhalterausdrucks ist ein Glob-Qualifikationsmerkmal , das besagt, dass nur reguläre Dateien abgeglichen werden.

Symbolische Links zu regulären Dateien stimmen nicht überein. Wenn Sie zu wechseln .*(-.), werden sie eingeschlossen, aber die Datei wird nicht im Archiv gespeichert, es sei denn, sie ist ebenfalls enthalten. Wenn Sie symbolische Verknüpfungen durch ihre Ziele ersetzen möchten, erstellen Sie Folgendes: .*(-.:A):AFügt den Änderungswert für die Verlaufserweiterung hinzu, mit dem alle symbolischen Verknüpfungen in einen Pfad aufgelöst werden, in dem keine symbolischen Verknüpfungen verwendet werden.

Gilles 'SO - hör auf böse zu sein'
quelle
3

Diese Antwort basiert auf der von slm, aber ich werde Ihnen auch zeigen, wie Sie Verzeichnisse einbinden, die mit beginnen .

So komprimieren Sie Punktdateien in Ihrem Home-Verzeichnis:

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

So schließen Sie Verzeichnisse ein:

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

Das ?ist optional im ersten Befehl, aber nicht im zweiten, sonst findwird das .(aktuelle) Verzeichnis mit einbezogen.

sudoman
quelle
1

wie wäre es mit:

tar -C $HOME -cvzf dotfiles.tgz .
anonym
quelle