Versteckte Dateien rekursiv kopieren - Linux

19

Gibt es eine einfache Möglichkeit, alle versteckten Dateien in einem Verzeichnis rekursiv in ein anderes Verzeichnis zu kopieren? Ich möchte nur alle Einstellungsdateien in einem Ausgangsverzeichnis sichern, nicht die normalen Dateien. Ich habe es versucht:

cp -R .* directory

es erkennt .und ..kopiert aber auch alle nicht versteckten Dateien rekursiv. Gibt es eine Möglichkeit, cp zu ignorieren .und zu bekommen ..?

Zifre
quelle
Gibt es einen Unterschied zwischen -rund -R?
Chaminda Bandara

Antworten:

15

Mein Liebling, dirs im Allgemeinen zu bewegen, war:

tar cvf - . | (cd /dest/dir; tar xvf -)

Der Befehl tariert das aktuelle Verzeichnis auf stdout und leitet es dann an eine Subshell weiter, die zuerst zum Zielverzeichnis wechselt, bevor der Befehl stdin entpackt wird. Einfach, direkt, erweiterbar - Überlegen Sie, was passiert, wenn Sie das () durch ein SSH auf einem anderen Computer ersetzen. Oder zur Beantwortung Ihrer Frage:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)
pjz
quelle
1
Danke, die Option zum Ausschließen ist genau das, was ich brauchte. Ich habe es bereits anders gemacht, aber ich werde es für zukünftige Zwecke aufbewahren. Dies scheint sehr flexibel zu sein (obwohl es vielleicht langsamer ist).
Zifre,
1
Guter Rat. Ich habe ein paar Verbesserungen: 1) Verwenden Sie cd /dest/dir && tar xvf -. Das &&hindert Sie daran, über das Quellverzeichnis zu blättern, wenn Sie einen Tippfehler im Ziel haben. 2) Sie benötigen nur das tar- vFlag für einen der tar-Befehle (oder keinen).
Tom Shaw
Meinetwegen. Ich war auch dafür bekannt, Dinge anders zu gruppieren: ein entferntes srcdir hierher zu kopieren, do(cd /src/dir && tar cf - .) | tar xvf -
pjz
17

Fast jedes Mal kann dies einfach gelöst werden mit:

cp -R .[a-zA-Z0-9]* directory

Es ist ziemlich ungewöhnlich, eine versteckte Datei zu haben, die nicht mit einem dieser Zeichen beginnt.

Andere Musterübereinstimmungen sind verfügbar ( .??*, .[^.]*) - siehe Kommentare

Alnitak
quelle
Das ignoriert nur.-Xyz - das Zeug in [] stimmt nur mit dem ersten Zeichen nach dem Punkt überein.
Hamish Downer
6
. [^.] * würde alles fangen
Falstro
1
... außer Sachen, die mit zwei Perioden beginnen.
Falstro
@roe - das ist auch eine schöne Version
Alnitak
@mish - ja, das habe ich auch in der Antwort gesagt.
Alnitak
11

Du könntest es gebrauchen rsync.

rsync -a ./ /some/other/directory/

Dadurch wird der Inhalt des aktuellen Verzeichnisses kopiert (einschließlich der Punktedateien, jedoch nicht einschließlich ..).

Rory
quelle
Einfach und funktioniert auch für versteckte Dateien in versteckten Ordnern.
user59183
für mich ist dies die weniger verwirrende und effektivste der angebotenen
lösungen
Gute Lösung. Ich brauchte es auch nicht über .gitdirs zu kopieren . Das Hinzufügen von -C bewirkt rsync -aC ./ /some/other/directory/
Folgendes
10

Ich flehe Sie an, Schritt weg von der einfachen Shell-Erweiterung auf der cpKommandozeile - die Shell-Erweiterung hat alle möglichen "interessanten" Eckfälle (unerwünschte Rekursion durch. Und., Leerzeichen, nicht druckbare Inhalte, Hardlinks, symbolische Links und usw.) Verwenden Sie findstattdessen (es ist im findutilsPaket enthalten, falls Sie es nicht installiert haben - was seltsam wäre, alle Distributionen installieren es standardmäßig):

find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;

Schritt für Schritt Erklärung:

  • -HVerursacht find, dass Symlinks nicht gefolgt werden (außer wenn es sich bei dem von Ihnen angegebenen Toplevel-Verzeichnisnamen um einen Symlink handelt; dieser wird folgen.)
  • /path/to/toplevel/dir/ soll natürlich von Ihnen durch den Pfad des Verzeichnisses ersetzt werden, in dem sich die zu sichernden Einstellungsdateien und Verzeichnisse befinden.
  • -maxdepth 1stoppt das findrekursive Absteigen in alle Verzeichnisse, deren Name mit einem Punkt beginnt. Wir brauchen es cpnicht, um uns zu beschweren, wir werden das für uns tun, wir brauchen nur die Namen auf dieser Ebene.
  • -name '.*'sagt, finddass wir alle Namen wollen, die mit einem Punkt beginnen. Dies funktioniert nicht richtig, wenn die Umgebungsvariable POSIXLY_CORRECTgesetzt ist, aber es ist selten (wenn überhaupt). Dies ist die erste Übereinstimmungsbedingung, die wir bisher angegeben haben.
  • a \( ....... \)ist ein und gefolgt von einer komplexeren Bedingung in Klammern (ich habe ..... verwendet, um es zu ersetzen, es wird unten erklärt.) Wir müssen die Klammern maskieren, da sie sonst von der Shell (falsch) interpretiert werden, daher der Backslash vor ihnen,
  • -type d -o -type f -o -type lsind drei Bedingungen mit einem oder zwischen ihnen. -type dStimmt mit Verzeichnissen, -type fregulären Dateien und -type lSymlinks überein. Sie können auswählen, was Sie möchten - wenn Sie beispielsweise keine Einstellungsverzeichnisse sichern möchten, lassen Sie dies weg -type d(und -onatürlich das Recht dahinter).
  • -exec ..... \;Weist findan, bei jedem Treffer einen Befehl auszuführen. Das Ende des Befehls wird durch ein Semikolon markiert, das wir erneut mit einem Backslash abschließen müssen, um eine Shell-Interpretation zu vermeiden. In dieser Befehlszeile müssen Sie angeben, {}wo der Name der aktuell ermittelten Übereinstimmung landen soll. Da Muscheln die geschweiften Klammern auch falsch interpretieren können, sollten Sie sie in Apostrophe setzen, wie in '{}'. Der Befehl, den wir in diesem Fall ausführen möchten, lautet: cp -a '{}' /path/to/destination/dir/(-a bedeutet Archiv, das in Unterverzeichnissen wiederkehrt, Symlinks als Links kopiert, Berechtigungen und erweiterte Attribute beibehält und /path/to/destination/dir/offensichtlich der Name des Zielverzeichnisses ist - ersetzen Sie es.)

Im Klartext findsagt diese Befehlszeile also Folgendes:

Beginnen Sie mit / path / to / toplevel / dir /. Steigen Sie nicht in Unterverzeichnisse ab. Finden Sie alle Verzeichnisse, Dateien und Symlinks, deren Name mit einem Punkt beginnt. Kopieren Sie die gefundenen Elemente nach / path / to / destination / dir /, um die Eigenschaften, Berechtigungen und erweiterten Attribute zu erhalten.

Mihai Limbăşan
quelle
1
find ist das nützlichste überhaupt.
Mr. Shiny und New 安 安
1
Gute Antwort. Obwohl ich lieber -exec ... ';' Das Vermeiden von Backslash bedeutet, dass dieser Befehl sowohl in CLI als auch in der crontab
funktioniert
8

Ich habe immer. ?? * verwendet, um versteckte Dateien zu finden, ohne "." und "..". Vielleicht fehlt ".a" oder so, aber ich habe nie eine davon.

Paul Tomblin
quelle
Auf jeden Fall schön und ordentlich :) +1
Falstro
Ich möchte nicht, dass es auf mysteriöse Weise scheitert, wenn es einige ".a" s
Zifre gibt.
Ich mag es, denn wenn Sie wissen, dass Sie keine versteckten Dateien für einzelne Zeichen haben, ist es sehr schnell zu tippen.
Paul Tomblin
Dies muss die beste Antwort sein. Es sollte nach oben gestimmt werden.
Ibn Saeed