Ich hoffte:
cp -R src/prog.js images/icon.jpg /tmp/package
würde eine symmetrische Struktur im Zielverzeichnis ergeben:
/tmp
|
+-- package
|
+-- src
| |
| +-- prog.js
|
+-- images
|
+-- icon.jpg
Stattdessen werden beide Dateien in / tmp / package kopiert. Eine flache Kopie. (Dies ist unter OSX).
Gibt es eine einfache Bash-Funktion, mit der ich alle Dateien, einschließlich der durch Platzhalter angegebenen Dateien (z. B. src / *. Js), an ihren rechtmäßigen Platz im Zielverzeichnis kopieren kann? Ein bisschen wie "für jede Datei ausführen mkdir -p $(dirname "$file"); cp "$file" $(dirname "$file")
", aber vielleicht ein einzelner Befehl.
Dies ist ein relevanter Thread, was darauf hindeutet, dass dies nicht möglich ist. Die Lösung des Autors ist für mich jedoch nicht so nützlich, da ich einfach eine Liste von Dateien, Platzhalter oder nicht, bereitstellen und alle in das Zielverzeichnis kopieren lassen möchte. IIRC MS-DOS xcopy macht dies, aber es scheint kein Äquivalent für cp zu geben.
cp --parents
ist eine illegale Option in OSX (BSD cp), abergcp
(GNU cp) funktioniert einwandfrei. Wenn es noch nicht in Ihrem System ist, verwenden Siebrew install coreutils
. U wird viele Utils mit g-Präfix haben.cp -R --parents
undrsync -rR
kopiert sowohl Dateien als auch Verzeichnisse relativ.Einweg:
quelle
-C
Option verwenden, um das chdir für Sie zu erledigen -tar cf - _files_ | tar -C /dest xf -
oder so ähnlich.Wenn Sie altmodisch sind, verwenden Sie alternativ cpio:
Natürlich können Sie die Dateiliste nach Herzenslust filtern.
Die Option '-p' ist für den Durchgangsmodus vorgesehen (im Gegensatz zu '-i' für die Eingabe oder '-o' für die Ausgabe). Das '-v' ist ausführlich (listet die Dateien auf, während sie verarbeitet werden). Das '-m' behält die Änderungszeiten bei. Das '-B' bedeutet 'große Blöcke' verwenden (wobei große Blöcke 5120 Bytes anstelle von 512 Bytes sind); es ist möglich, dass es heutzutage keine Wirkung hat.
quelle
-print0
mit der Kombination von--null
Optionen zu verwenden, damit es nicht mit Sonderzeichen und dergleichenfind . -print0 | cpio -pvdmB --null /target
cpio
auf diese Aufgabe. Ich bin damit einverstanden, dass die Optionen-print0
und-null
verwendet werden sollten, andernfalls wird Ihnen irgendwann jemand Ordner mit 'Sonderzeichen' (Leerzeichen, höchstwahrscheinlich) geben und etwas wird passieren. Nicht, dass ich aus persönlicher Erfahrung spreche, aber Sie könnten versuchen, eine Reihe von Dateien zu sichern und nur die Hälfte davon zu sichern, da Leerzeichen in Dateinamen enthalten sind. (Okay, ich spreche aus persönlicher Erfahrung.)cpio
wie gezeigt, wenn Dateinamen Zeilenumbrüche enthalten. Normalerweise wird eine Fehlermeldung angezeigt, dass zwei (oder mehr) Dateinamen nicht für jede neue Zeile in einem Dateinamen gefunden werden. (Manchmal erhalten Sie möglicherweise weniger Nachrichten - dies erfordert jedoch erhebliche Sorgfalt bei der Erstellung des Testfalls.) Als ich benutztecpio
, gab es keine--null
Option; Double-Dash-Optionen waren nicht Teil der SVR4-Optionsnotationen, und das Konzept von-print0
war auch nicht vorhandenfind
. Aber das ist lange her (zum Beispiel Mitte der 90er Jahre, bevor Linux die Dominanz erlangte).xargs
in der Mischung - sie wird im Leerraum aufgeteilt - Leerzeichen, Tabulatoren, Zeilenumbrüche. OTOH, ich bin mir nicht sicher, wie oder warum du das machen würdest. Das GNU-cpio
Manul im Ausgabemodus enthält ungefähr einen Dateinamen pro Zeile. Das SVR4-Benutzerhandbuch (gedruckt 1990) ist vage:cpio -o
( Kopiermodus ) liest die Standardeingabe, um eine Liste von Pfadnamen zu erhalten, und kopiert diese Dateien zusammen mit dem Pfadnamen und den Statusinformationen in die Standardausgabe. Es besteht daher die Möglichkeit, dass Namen an Leerzeichen gebrochen wurden.Die Option -R von rsync macht das, was Sie erwarten. Es ist ein sehr funktionsreicher Dateikopierer. Beispielsweise:
Beispielergebnisse:
quelle
rsync natürlich! Tutorial hier. und hier
Oder unisono
quelle
Versuchen...
Also für das, was du ursprünglich gemacht hast ...
oder
quelle
echo
oder$v
hier. Auch diese Methode schlägt fehl, wenn das entsprechende Verzeichnis im Ziel nicht vorhanden ist.