it-swarm.com.de

Wie kann man "cp" zwingen, ein Verzeichnis zu überschreiben, anstatt ein neues zu erstellen?

Ich versuche, ein Bash-Skript zu schreiben, das ein vorhandenes Verzeichnis überschreibt. Ich habe ein Verzeichnis foo/ Und ich versuche, bar/ Damit zu überschreiben. Aber wenn ich das mache:

cp -Rf foo/ bar/

ein neues Verzeichnis bar/foo/ wird erstellt. Ich will das nicht. Es gibt zwei Dateien in foo/; a und b. Es gibt auch Dateien mit dem gleichen Namen in bar/. Ich möchte, dass foo/a Und foo/bbar/a Und bar/b Ersetzen.

76
saketrp

Sie können dies mit -T Option in cp.
Siehe Manpage für cp.

-T, --no-target-directory
    treat DEST as a normal file

So wie in Ihrem Beispiel, folgt die Dateistruktur.

$ tree test
test
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

Sie können den deutlichen Unterschied erkennen, wenn Sie -v für Verbose.
Wenn Sie nur -R Möglichkeit.

$ cp -Rv foo/ bar/
`foo/' -> `bar/foo'
`foo/b' -> `bar/foo/b'
`foo/a' -> `bar/foo/a'
 $ tree
 |-- bar
 |   |-- a
 |   |-- b
 |   `-- foo
 |       |-- a
 |       `-- b
 `-- foo
     |-- a
     `-- b
3 directories, 6 files

Wenn Sie die Option -T überschreibt den Inhalt, behandelt das Ziel wie eine normale Datei und nicht wie ein Verzeichnis.

$ cp -TRv foo/ bar/
`foo/b' -> `bar/b'
`foo/a' -> `bar/a'

$ tree
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

Dies sollte Ihr Problem lösen.

93
Saurabh Meshram

Mach es in zwei Schritten.

rm -r bar/
cp -r foo/ bar/
34

Wenn Sie sicherstellen möchten, dass _bar/_ mit _foo/_ identisch ist, verwenden Sie stattdessen rsync:

_rsync -a --delete foo/ bar/
_

Wenn sich nur ein paar Dinge geändert haben, wird dies viel schneller ausgeführt als das Entfernen und erneute Kopieren des gesamten Verzeichnisses.

  • _-a_ ist der 'Archivierungsmodus', der Dateien in _foo/_ nach _bar/_ kopiert.
  • _--delete_ entfernt zusätzliche Dateien, die nicht in _foo/_ enthalten sind, auch aus _bar/_, um sicherzustellen, dass _bar/_ identisch ist
  • Wenn Sie sehen möchten, was es tut, fügen Sie _-vh_ hinzu, damit es ausführlich und für Menschen lesbar ist
  • Hinweis: Der Schrägstrich nach foo ist erforderlich, andernfalls kopiert rsync _foo/_ nach _bar/foo/_ und überschreibt _bar/_ selbst. [.____]
    • (Schrägstriche nach Verzeichnissen in rsync sind verwirrend. Wenn Sie interessiert sind, finden Sie hier den Überblick. Sie weisen rsync an, sich auf Inhalt des Verzeichnisses und nicht auf das Verzeichnis selbst zu beziehen Um also von Inhalt von _foo/_ auf den Inhalt von _bar/_ zu überschreiben, verwenden wir für beide einen Schrägstrich on beides nicht, allerdings interpretiert rsync den Zielpfad immer so, als ob er einen Schrägstrich enthält, obwohl kein Schrägstrich im Quellpfad vorhanden ist Passen Sie es an den automatisch hinzugefügten Schrägstrich im Zielpfad an, wenn Sie Inhalt von _foo/_ in _bar/_ und nicht in das Verzeichnis _foo/_ selbst kopieren möchten Landung in _bar/_ als _bar/foo_.)

rsync ist sehr mächtig und nützlich, wenn Sie neugierig sind, was es sonst noch kann (z. B. Kopieren über ssh).

21
Tom Potter

Verwenden Sie diesen cp Befehl:

cp -Rf foo/* bar/
11
anubhava

Der folgende Befehl stellt sicher, dass Dotfiles (versteckte Dateien) in der Kopie enthalten sind:

$ cp -Rf foo/. bar
7
Brynn Mahsman

Sehr ähnlich wie @Jonathan Wheeler:

Wenn Sie sich nicht erinnern möchten, aber bar nicht umschreiben möchten:

rm -r bar/
cp -r foo/ !$

!$ zeigt das letzte Argument Ihres vorherigen Befehls an.

3
Michael Dimmitt

Versuchen Sie, diesen aus zwei Schritten zusammengesetzten Befehl zu verwenden:

rm -rf bar && cp -r foo bar
0
Yahor M

Die Operation, die Sie definiert haben, ist eine "Zusammenführung" und Sie können dies nicht mit cp tun. Wenn Sie jedoch nicht nach einer Zusammenführung suchen und den Ordner bar verlieren möchten, können Sie einfach rm -rf bar, um den Ordner zu löschen, und dann mv foo bar, um es umzubenennen. Dies nimmt keine Zeit in Anspruch, da beide Vorgänge von Dateizeigern und nicht von Dateiinhalten ausgeführt werden.

0
atiyil