Kopieren Sie alle Dateien und Ordner mit Ausnahme von Subversion-Dateien und -Ordnern unter OS X

14

Ich versuche, alle Dateien und Ordner von einem Verzeichnis in ein anderes zu kopieren, schließe jedoch bestimmte Dateien aus. Insbesondere möchte ich Subversion-Dateien und -Ordner ausschließen. Ich hätte jedoch gerne eine allgemeine und dennoch prägnante Lösung.

Ich stelle mir vor, dass ich in naher Zukunft mehrere Dateitypen ausschließen muss. Zum Beispiel möchte ich vielleicht .svn, * .bak und * .prj ausschließen.

Hier ist, was ich so zusammengestellt habe, aber es funktioniert nicht für mich. Der erste Teil, finde funktioniert, aber ich mache etwas falsch mit xargs und cp . Ich habe versucht , cp mit und ohne -R. Außerdem verwende ich OS X und es scheint, dass es eine weniger funktionsfähige Version von xargs als Linux-Systeme gibt.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory
Michael Prescott
quelle
Ich kann mich irren, aber ich denke, das ist schwieriger als Sie denken. Selbst wenn Ihr findBefehl ordnungsgemäß -prunezum Ausschließen von .svn-Elementen verwendet wird, übergeben Sie das -RFlag, cpdas angibt, dass dieser Befehl rekursiv sein soll. Wenn Sie dies tun, verlieren Sie die Granularität, die Sie im findBefehl hatten. Ich bin mit diesem für eine Minute zu basteln gehen, aber ich denke , die Antwort ist nicht auf den Einsatz -Rin dem cpBefehl.
Telemachus
Es scheint für mich auf einem Linux-System zu funktionieren. Können Sie genauer sagen, was "es funktioniert nicht" bedeutet? Fehlermeldungen? Dateien werden / werden nicht kopiert, wie Sie es erwarten?
Bis auf weiteres angehalten.
Es ist die -RFlagge, da bin ich mir ziemlich sicher. Entfernen Sie das und Sie sollten in Ordnung sein (obwohl Sie vielleicht hinzufügen möchten, um -mindepth 1den obersten Ordner zu ignorieren, den Sie nicht kopieren möchten, nehme ich an)
Telemachus
Normalerweise mache ich diese Dinge, indem ich alles kopiere und dann die unerwünschten Dateien in den Zielverzeichnissen lösche. Das ist oft viel einfacher.
Jan Doggen

Antworten:

22

(Nach dem erneuten Lesen der Frage bearbeitet. Der Fragesteller sagt, dass rsync nicht installiert ist.)

Ein mögliches Problem mit Ihrer find / xargs-Lösung sind Leerzeichen in den Dateinamen. Um das zu umgehen, weisen Sie find und xargs an, ein Nullzeichen (ASCII 0) zu verwenden, um die gefundenen Dateien zu trennen:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

Wenn Sie feststellen, dass Rsync verfügbar ist, denke ich immer noch, dass Rsync die weitaus bessere Lösung ist:

Verwenden Sie rsync mit der Option -C. Von der rsync-Manpage :

Dies ist eine nützliche Abkürzung zum Ausschließen einer Vielzahl von Dateien, die Sie häufig nicht zwischen Systemen übertragen möchten. Es verwendet einen ähnlichen Algorithmus wie CVS, um zu bestimmen, ob eine Datei ignoriert werden soll.

Dadurch wird rsync angewiesen, diese Muster zu ignorieren:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

Beispielsweise:

rsync -avC /path/to/source/directory /path/to/destination/directory

(Hinweis: Wenn Sie noch nicht mit rsync vertraut sind, lesen Sie auf dieser Manpage, wie rsync mit einem abschließenden Schrägstrich im Quellpfad umgeht. Wenn Sie den Schrägstrich einfügen, verhält es sich anders als wenn Sie es nicht tun. Search for 'abschließender Schrägstrich')

Doug Harris
quelle
Oh Ratten, ich habe gerade Ihre Frage noch einmal gelesen und festgestellt, dass Sie gesagt haben, dass Sie kein Rsync installiert haben. Auf meinem MacBook Pro (OS X 10.6.1) befindet es sich in / usr / bin / rsync. Es wurde für mich auch unter Tiger (10.4) und Leopard (10.5) installiert.
Doug Harris
Ich bin mir ziemlich sicher, dass Sie (und das OP) das -RFlag im xargsTeil des Befehls nicht wollen .
Telemachus
Guter Fang, das habe ich von der ursprünglichen Frage übernommen. Wird jetzt bearbeiten.
Doug Harris
1
Vielen Dank, Doug! Eine Sache, die ich predige, "benutze das richtige Werkzeug für den Job". Ich bin kürzlich von der Windows-Welt zu OSX gekommen und fummele immer noch in Unwissenheit herum. Ich habe die gleiche Frage in einem Linux-Kanal gepostet, und jemand sagte schnell: "rsynch" verwenden. Ich habe "rsynch" im Terminal eingegeben und festgestellt, dass sie nicht existiert, und habe den Fund weiter untersucht xargs Ansatz. Ich bin so ein bisschen stur. Wie auch immer, OSX hat standardmäßig "rsync" und Ihr Beitrag war sehr hilfreich. Ich habe hier noch nicht genug Erfahrung, um zu wissen, was besser ist, aber rsync ist sicher viel prägnanter. Vielen Dank!
Michael Prescott
Wenn Sie zusätzlich zu Ihrer Arbeit unter OS X auch noch mit Linux-Computern arbeiten, ist es Ihrer Meinung nach die Zeit wert, sich mit der Verwendung von rsync vertraut zu machen. Die Hauptfunktionalität ist das intelligente Kopieren nur des geänderten Materials (wie beispielsweise das Kopieren unter Windows, wenn Sie damit vertraut sind). Da es nur das Delta kopiert, ist es eine großartige Möglichkeit, Sicherungen, Code-Bereitstellungen und Ähnliches (ohne Time Machine) durchzuführen.
Doug Harris
2

Keine allgemeine Lösung, aber ... Sie können den Befehl svn export verwenden, um eine Kopie des Arbeitsbereichs ohne die .svn-Metadatenordner zu erstellen.

Chris Nava
quelle
Um nicht beleidigend zu sein, aber ich bin mir nicht sicher, warum über diese Antwort abgestimmt wird. Ich bin mir der Fähigkeiten von svn bewusst, aber "Ich hätte gerne eine allgemeine, aber prägnante Lösung. Ich kann mir vorstellen, dass ich in naher Zukunft mehrere Dateitypen ausschließen muss"
Michael Prescott,
2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

Wenn Sie möchten, können Sie sogar "pv" oder ähnliches zwischen die beiden Teerprozesse setzen.

Akira
quelle
2

Eine schmutzige, aber schnelle und prägnante Art:

cp -r source destination
find destination -iname .svn |xargs rm -rf

Dies kopiert ein Verzeichnis in ein anderes (daher die rekursive Option -r) und löscht dann rekursiv alle Namen .svn(Groß- / Kleinschreibung wird ignoriert).

michele
quelle
1

Ich würde es anders machen, indem ich Teer und seinen Ausschlussmechanismus benutze.

Von im Zielverzeichnis:

tar -X excludefile -C source -f - . | tar xf -

Dies führt dazu, dass die Quelle ausgewählt wird, der Inhalt unter Ausschluss der in Ausschlussdatei aufgeführten Elemente tariert und anschließend in das aktuelle Verzeichnis entpackt wird.

KeithB
quelle
In der Tat eine elegante Lösung.
Nick Stinemates
Nun, es ist die gleiche Antwort, die ich später gegeben habe. und du musst im
Zielverzeichnis sein
0

Bearbeitete Antwort : Das Problem ist, dass -Rdas Kopieren rekursiv wird und Sie am Ende die versteckten Dateien kopieren. Folgendes würde ich verwenden:

find source/  -mindepth 1 -not \( -name .svn -prune \) | xargs -Iitem cp item target/

Das -mindepth 1Flag weist findan, das Verzeichnis der obersten Ebene zu ignorieren. Da Sie den gesamten Inhalt dieses Verzeichnisses in ein neues Verzeichnis der obersten Ebene kopieren möchten, gehe ich davon aus, dass Sie dies nicht möchten.

Wie Chris Nava in seiner Antwort sagt , gibt es bereits eine integrierte Möglichkeit, dies zu tun, wenn wir über SVN-Ordner sprechen. Da Sie jedoch nach einer allgemeineren Lösung gefragt haben, kann dies ein wenig helfen.

Telemachus
quelle
Danke Telemachus, es ist hilfreich. Ich habe nicht die Erfahrung, Kritik zu üben, aber ich werde wiederholen, was mir seit meinem ursprünglichen Beitrag gesagt wurde. "xargs is broken" Der unbekannte IRC-Kommentator, der mir sagte, dass er mich dazu inspiriert hat, mich ein bisschen mehr umzusehen, und ich denke, dass Doug Harris Antwort das Problem anspricht. Das weist xargs an, Nullzeichen zu verwenden. Ich denke das ist der -0 Schalter?
Michael Prescott
@Michael: xargsist nicht defekt, aber auf Unix-ähnlichen Systemen werden standardmäßig keine Dateinamen (oder Verzeichnisnamen) mit Leerzeichen darin verwendet. Wenn Ihre Dateinamen (oder Verzeichnisnamen) Leerzeichen oder "lustige" Zeichen enthalten, müssen Sie zusätzliche Arbeit leisten, um damit umzugehen. (In GNU findgibt es manwegen dieses Problems einen ganzen Abschnitt auf der Seite mit dem Namen "UNUSUAL FILENAMES".) Das -0Flag in xargsund -print0für findHilfe zur Behandlung dieser Probleme. Ich verspreche Ihnen jedoch, dass Sie -Rin Ihrem Kopierbefehl nicht verwenden möchten . Es wird alles, was Sie tun, rückgängig machen, um die SVN-Verzeichnisse zu vermeiden.
Telemachus
0

Ich nehme an, es hängt davon ab, wie groß Ihr Baum ist, aber warum nicht erst alles kopieren und dann die .svn-Ordner zuschneiden?

find /dest-dir -type d -name .svn -exec rm -rf {} \;

?

Steve Folly
quelle
Ohne Benchmarking ist mein erster Gedanke, dass dies eine doppelte Verschwendung von CPU-Zyklen ist: das Kopieren und das Entfernen. Es kann etwas mehr Zeit in Anspruch nehmen find, den richtigen Befehl zu erstellen , aber Sie tun dies nur einmal. Sie können den Befehl hunderte Male verwenden, sobald Sie es richtig verstanden haben.
Telemachus
@Telemachus - stimmt, aber das ist, was Computer können (sollen) - die kniffligen Dinge tun, damit wir nicht müssen! Wirklich - was schadet es, einige Dateien nur zu kopieren, um sie bald danach zu löschen, wenn es bedeutet, dass die Befehle, die Sie erfinden, sehr einfach sind?
Steve Folly
@Steve: Es gibt wirklich keinen Schaden. Soweit es geht, ist dies eine gute Lösung. Es folgt einem Grundsatz, den ich mag: "Mach das Einfachste, was geht." Andererseits verstößt es gegen ein anderes Prinzip, das ich noch mehr mag: "Lerne deine Werkzeuge." Ich würde es vorziehen zu lernen, wie man sich findselbst besser benutzt, damit ich das nicht tun musste. Aber Sie haben Recht: An dieser Lösung ist nichts wirklich Falsches.
Telemachus
@Telemachus: Ich bin mit "Learn your tools" einverstanden. Als ich angefangen habe, hätte mein Suchbefehl oben für mich dann sicher sehr kryptisch ausgesehen :-)
Steve Folly
0

Vergiss grep -v nicht

find . | grep -v .svn
Nick Stinemates
quelle
Dieser Befehl macht nicht das, was Sie denken.
Juan A. Navarro
0

Sie können auch das Gegenteil tun. Kopieren Sie alles und löschen Sie die .svn-Ordner mit dem folgenden Befehl:

find . | grep ".svn" | xargs rm -rf
devXen
quelle