Wie kopiere ich versteckte (beginnend mit einem Punkt) Dateien und Unterverzeichnisse unter Linux?

10

Wie kopiere ich versteckte Dateien und versteckte Unterverzeichnisse (die mit einem Punkt beginnen) in Ordner A in Ordner B? Zum Beispiel, wenn ich diese Struktur habe:

A/a
A/b
A/.a
A/.b/
A/.b/somefile
A/.b/.c

Ich möchte nur die versteckten Dateien und versteckten Unterverzeichnisse in A nach B kopieren:

B/.a
B/.b/
B/.b/somefile
B/.b/.c

Ich habe diesen Befehl bereits ausprobiert: cp A/.* Bvon dieser anderen Superuser-Frage . Die Unterverzeichnisse werden jedoch nicht kopiert. Auch versucht cp -r A/.* B, aber es kopiert, .so dass ich mit einer genauen Kopie von A (einschließlich der normalen Dateien) ende. Jede Hilfe wird geschätzt.

gaboroncancio
quelle

Antworten:

16

Solange Sie nur nach versteckten Dateien und Ordnern auf der Ebene A suchen und dies beispielsweise nicht möchten

A/b/.hidden

Um kopiert zu werden, sollten Sie in der Lage sein, Folgendes zu verwenden:

cp -r A/.[^.]* B

Es bedeutet im Grunde, alles zu kopieren, was mit einem .und dann einem anderen Zeichen als einem beginnt, .das herausfiltert .und..

Bearbeiten: Das -p wurde aus dem Befehl cp entfernt, da Asker nicht angegeben hat, dass er Eigentümer, Daten usw. beibehalten möchte.

Allgegenwart
quelle
Dies funktioniert für die in der Frage angegebenen Beispieldatei- und Verzeichnisnamen, aber der Text der Frage lautet "versteckte Dateien und versteckte Unterverzeichnisse (diejenigen, die mit einem Punkt beginnen)", und diese Antwort findet keine Dateien und Verzeichnisse, deren Namen mit beginnen zwei Punkte; zB , ..c.
Scott
Das ist ein ziemlicher Randfall, aber dennoch ein berechtigtes Anliegen. Daran hatte ich nicht gedacht. Sie könnten dies erklären, indem Sie zu wechseln, .*[^.]aber dann würden Sie Dateien verpassen, die mit einem enden .. Ich denke, Sie würden in der Tat ein erweitertes Globbing benötigen, um wirklich alle Fälle zu berücksichtigen.
Allgegenwart
4

Das Problem dabei A/.*ist, dass es das Verzeichnis gibt, .in Adem auch das Muster übereinstimmt.

Sie können erweiterte Glob-Muster aktivieren und Folgendes verwenden:

shopt -s extglob
cp -r A/.!(?(.)) B    

Es stimmt mit Dateien überein, deren Name mit einem Punkt beginnt und deren zweites Zeichen weder ein Punkt noch nichts ist (? (.) Mit nichts oder einem Punkt übereinstimmt ,! (...) negiert es, dh! (? (.)) Stimmt mit allem anderen überein als nichts oder ein Punkt).

Choroba
quelle
+1 für eine korrekte Antwort. Beachten Sie, dass .!(@(|.))(AFAICT) dem oben genannten entspricht, (IMNSHO) etwas klarer und nur ein Zeichen länger.
Scott
3

In solchen Fällen würde die Verwendung findanstelle der folgenden empfohlen cp:

find A/ -type f -maxdepth 1 -name '.*' -exec cp -p {} B/ \;

Die grundlegende Syntax sieht folgendermaßen aus:

  • find A/ -type f: findElemente im Verzeichnis, A/deren Typ eine Datei ist (anstelle eines Verzeichnisses)…
  • -maxdepth 1 -name '.*': Dazu für eines maxdepthvon 1 Verzeichnissen und dessen namebeginnt mit ..
  • -exec cp -p {} B/ \;: Und sobald diese Dateien gefunden sind, execder cpBefehl mit einem -pFlag zum Beibehalten von Datum / Uhrzeit von der Quelle ( {}) bis zum Ziel von B/.

Ich verwende gerne maxdeptheine Steuerungsebene, damit ich nicht versehentlich ein ganzes Dateisystem kopiere. Aber zögern Sie nicht, das zu entfernen.

JakeGould
quelle
0
 for item in `find A -type d | grep -E "\."` ; do cp -r $item B ; done
  • find A -type d Bietet eine rekursive Liste in A mit nur Verzeichnissen
  • grep -E "\." filtert Verzeichnisse mit einem Punkt (dh versteckte Verzeichnisse)
  • Die Option -E wurde hier benötigt, da sie ohne sie auch "aktuelles Verzeichnis" bedeutet
  • Der Backslash besteht darin, die Bedeutung von "jedem Zeichen" unter regulären Ausdrücken zu vermeiden.
  • cp -r rekursiv kopieren

Ich habe die Datei- und Ordnerstruktur für A erstellt und den Befehl in Git Bash ausgeführt (ich bin gerade nicht unter Linux) und es hat funktioniert.

Malarres
quelle
Dies wird unterbrochen, wenn Dateien Leerzeichen oder Sonderzeichen in ihrem Namen oder Pfad enthalten.
Slhck
Danke, dass du es bemerkt hast :) Eigentlich habe ich mich auf den "Testfall" von @gaboroncancio beschränkt. Wenn Sie mir eine andere Testbatterie geben können, kann ich versuchen, diese zu verbessern (natürlich, wenn Sie möchten, verbessern Sie sie entweder selbst, indem Sie diese Antwort bearbeiten oder eine neue Antwort erstellen)
malarres
Sie könnten die Punktedateien einfach in einen Ordner mit dem Namen legen A B, und dann würde es unerwartet wirken, weil es auf erweitert würde cp -r A B/.dotfile B. Der allgemeine Rat ist, überhaupt nicht zu analysieren findoder lsauszugeben . Wenn Sie verwenden find, sollten Sie auch eigene Filteroptionen verwenden und nicht grep, und wenn Sie die findAusgabe an eine andere Stelle weiterleiten, verwenden -print0Sie den gewünschten Befehl oder rufen Sie ihn direkt auf. Siehe das find Handbuch .
Slhck
Noch allgemeiner ist es beim Arbeiten mit Dateien am sichersten, Shell-Globs zu verwenden, wie in anderen Antworten erläutert (obwohl diese häufig extglobfestgelegt werden müssen).
Slhck
Danke für den Link. Lassen wir finddann die Analyse.
Malarres
0

Alternativ können Sie diesen anderen Befehl verwenden, wenn das zweite Zeichen alphanumerisch ist ( Quelle ):

cp -r A/.[a-zA-Z0-9]* B
gaboroncancio
quelle
Dies funktioniert für die in der Frage angegebenen Beispieldatei- und Verzeichnisnamen, aber der Text der Frage lautet "versteckte Dateien und versteckte Unterverzeichnisse (diejenigen, die mit einem Punkt beginnen)", und diese Antwort findet keine Dateien und Verzeichnisse, deren Namen mit beginnen ein Punkt und ein Sonderzeichen; zB .@foooder ..c.
Scott
Deshalb weise ich darauf hin, dass es funktioniert, wenn das zweite Zeichen alphanumerisch ist. ;)
gaboroncancio