Ich suche nach einem Shell-Skript, das Dateien aus einem Verzeichnis in ein anderes zusammenführt.
Stichprobe:
html/
a/
b.html
index.html
html_new/
a/
b2.html
b.html
Verwendung:
./mergedirs.sh html html_new
Ergebnis:
html/
a/
b.html
b2.html
index.html
html/a/b.html
wurde ersetzt durch html_new/a/b.html
html/a/b2.html
wurde kopiert von html_new/a/b2.html
html/index.html
wurde unberührt gehalten
cp -r html_new/* html
? Sie können dashtml_new
Verzeichnis anschließend entfernen .Antworten:
Sie wollen wahrscheinlich nur
cp -R $1/* $2/
- das ist eine rekursive Kopie.(Wenn möglicherweise versteckte Dateien vorhanden sind (deren Namen mit einem Punkt beginnen), sollten Sie diesem Befehl ein Präfix voranstellen,
shopt -s dotglob;
um sicherzustellen, dass sie übereinstimmen.)quelle
cp -RT source/ destination/
Alle Dateien und Verzeichnisse in
source
landen indestination
. Zum Beispielsource/file1
wird nach kopiertdestination/file1
.Das
-T
Flag wird nichtsource/file1
mehr kopiertdestination/source/file1
. (Untercp
macOS wird das-T
Flag leider nicht unterstützt .)quelle
cp -r source/ destination
- es ist schwierig, das / genau wie angegeben zu verwenden.Schauen Sie sich rsync an
Rsync hat eine Menge Flags zu setzen. Weitere Informationen finden Sie in der Manpage zu rsync
quelle
Verwenden Sie einfach rsync - es ist ein großartiges Tool zum Kopieren und Zusammenführen lokaler Dateien sowie zum Remote-Kopieren.
Beachten Sie, dass der abschließende Schrägstrich im Quellordner erforderlich ist, um nur den Inhalt des Quellordners in das Ziel zu kopieren. Wenn Sie es weglassen, werden der Quellordner und sein Inhalt kopiert. Dies ist wahrscheinlich nicht das, wonach Sie suchen, da Sie Ordner zusammenführen möchten.
quelle
rsync -av /path/to/source_folder/ /path/to/destination_folder/
Obwohl diese Frage und ihre akzeptierte Antwort uralt sind, füge ich meine Antwort hinzu, da die derzeit vorhandenen Fragen
cp
entweder einige Randfälle nicht behandeln oder interaktiv arbeiten müssen. Oft spielen Edge-Cases / Skriptfähigkeit / Portabilität / mehrere Quellen keine Rolle. In diesem Fall gewinnt die Einfachheit, und es ist besser,cp
direkt mit weniger Flags (wie in anderen Antworten) zu verwenden, um die kognitive Belastung zu verringern - aber für diese anderen Zeiten (oder für eine robust wiederverwendbare Funktion) Dieser Aufruf / diese Funktion ist nützlich und übrigens nicht bash-spezifisch (mir ist klar, dass es sich bei dieser Frage um Bash handelt, also ist das in diesem Fall nur ein Bonus). Einige Flags können abgekürzt werden (zB mit-a
), aber ich habe alle explizit in Langform aufgenommen (außer-R
siehe unten) zur Erläuterung. Entfernen Sie einfach alle Flags, wenn es eine Funktion gibt, die Sie speziell nicht möchten (oder wenn Sie ein Nicht-Posix-Betriebssystem verwenden oder Ihre Versioncp
dieses Flags nicht verarbeitet - ich habe dies auf GNU Coreutils 8.25 getestetcp
):mergedirs() { _retval=0 _dest="$1" shift yes | \ for _src do cp -R --no-dereference --preserve=all --force --one-file-system \ --no-target-directory "${_src}/" "$_dest" || { _retval=1; break; } done 2>/dev/null return $_retval } mergedirs destination source-1 [source-2 source-3 ...]
Erläuterung:
-R
: hat eine subtil andere Semantik als-r
/--recursive
auf einigen Systemen (insbesondere in Bezug auf spezielle Dateien in Quellverzeichnissen), wie in dieser Antwort erläutert--no-dereference
: Folgen Sie niemals symbolischen Links in SOURCE--preserve=all
: Behalten Sie die angegebenen Attribute bei (Standard: Modus, Besitz, Zeitstempel), wenn möglich zusätzliche Attribute: Kontext, Links, xattr, alle--force
: Wenn eine vorhandene Zieldatei nicht geöffnet werden kann, entfernen Sie sie und versuchen Sie es erneut--one-file-system
: Bleiben Sie in diesem Dateisystem--no-target-directory
: Treat DEST als normale Datei (erklärt in in dieser Antwort , nämlich:If you do a recursive copy and the source is a directory, then cp -T copies the content of the source into the destination, rather than copying the source itself.
)yes
]: Auch wenn--force
in diesem speziellen rekursiven Moduscp
noch gefragt wird, bevor jede Datei überlastet wird, erreichen wir eine Nicht-Interaktivität, indem wir die Ausgabe von dortyes
an sie weiterleiten/dev/null
] weitergeleitet: Dies dient dazu, die unordentliche Reihe von Fragen nach dem Vorbild von zum Schweigen zu bringencp: overwrite 'xx'?
1
wenn ein Fehler aufgetreten istÜbrigens:
--reflink=auto
Erstellen sogenannter "Light Copies" (Copy-on-Write) mit den gleichen Geschwindigkeitsvorteilen wie beim Hardlink und den gleichen Größenvorteilen bis und in umgekehrtem Verhältnis um wie viel die Dateien in der Zukunft divergieren). Dieses Flag wird in der letzten GNU akzeptiertcp
und ist mehr als ein No-Op mit kompatiblen Dateisystemen auf neueren Linux-Kerneln. YMWV-viel auf anderen Systemen.quelle
cd html cp -r . /path/to/html_new
quelle
Würde nicht
cp -r
funktionieren?oder (da die erste Version keine ".something" -Dateien kopiert)
cd html_new; cp -r . ../html
Bitte beachten Sie, dass
-r
aus Pipes gelesen wird, wenn es sich bei einer der Dateien im kopierten Verzeichnis um Pipes handelt. Um dies zu vermeiden, verwenden Sie-R
stattdessen.quelle
-n
(kein Clobber) oder-f
(erzwingen), vorhandene Dateien beizubehalten oder zu überschreiben.