Kopieren Sie nur reguläre Dateien von einem Verzeichnis in ein anderes

12

Ich möchte einen Inhalt von Verzeichnis 1 in Verzeichnis 2 kopieren. Ich möchte jedoch nur Dateien (und keine Verzeichnisse) aus meinem Verzeichnis 1 kopieren. Wie kann ich das tun?

cp dir1/* dir2/*

dann habe ich noch das verzeichnisproblem.

Außerdem haben alle meine Dateien keine Erweiterung . wird den Trick nicht tun

user1058398
quelle
1
Ich weiß nicht, was Erweiterungen damit zu tun haben.
Strg-Alt-Delor
1
cp dir1/* dir2odercp -t dir2 dir1/*
Strg-Alt-Delor
@richard In der DOS-Welt gibt es eine weit verbreitete Angewohnheit, keine Erweiterungen für Verzeichnisse zu verwenden, die bis zu einem gewissen Grad erhalten bleibt. Einige Leute gehen davon aus, dass es sich bei einem Punkt nicht um ein Verzeichnis handelt und umgekehrt.
Gilles 'SO - hör auf böse zu sein'
ok aber immer noch nicht relevant.
Strg-Alt-Delor

Antworten:

18
cp dir1/* dir2

cpVerzeichnisse werden nicht kopiert, es sei denn, Sie werden ausdrücklich dazu aufgefordert ( --recursivesiehe z. B. siehe man cp).

Hinweis 1: cp Wird höchstwahrscheinlich mit einem Status ungleich Null beendet, die Dateien wurden jedoch trotzdem kopiert. Dies kann ein Problem sein , wenn Befehle Verkettungs basierend auf Exit - Codes: &&, ||, if cp -r dir1/* dir2; then ...usw. (Dank contrebis für seinen eigenen Kommentar zu diesem Thema )

Hinweis 2 : cpErwartet, dass der letzte Parameter ein einzelner Dateiname oder ein einzelnes Verzeichnis ist. *Nach dem Namen des Zielverzeichnisses sollte wirklich kein Platzhalter stehen . dir2\*wird von der Shell genauso wie erweitert dir1\*. Unerwartete Dinge werden passieren:

  • Wenn dir2leer ist und abhängig von Ihrer Shell und Einstellungen:
    • Möglicherweise wird nur eine Fehlermeldung angezeigt. Dies ist das beste Szenario.
    • dir2/*wird wörtlich genommen (auf der Suche nach einer Datei / einem Verzeichnis mit dem Namen *), was wahrscheinlich auch zu einem Fehler führt, sofern er nicht *tatsächlich existiert.
    • dir2/*Es wird nur vollständig aus dem Befehl entfernt und verlassen cp dir1/*. Was je nach Erweiterung von dir1/*sogar Daten zerstören kann:
      • Wenn dir1/*nur eine Datei oder ein Verzeichnis übereinstimmt, erhalten Sie eine Fehlermeldung von cp.
      • Wenn dir1/*genau zwei Dateien übereinstimmen, wird eine von der anderen überschrieben ( Bad ).
      • Wenn dir/*mehrere Dateien übereinstimmen und die letzte Übereinstimmung eine ist, wird eine Fehlermeldung angezeigt.
      • Wenn die letzte Übereinstimmung von dir/*ein Verzeichnis ist, werden alle anderen Übereinstimmungen in dieses Verzeichnis verschoben.
  • Wenn dir2es nicht leer ist, kommt es wieder darauf an:
    • Wenn die letzte Übereinstimmung von dir2/*ein Verzeichnis ist dir1/*und die anderen Übereinstimmungen von dir2/*in verschoben werden.
    • Wenn die letzte Übereinstimmung von dir2/*eine Datei ist, wird wahrscheinlich eine Fehlermeldung angezeigt, es sei denn , esdir1/* stimmt nur mit einer Datei überein.
Adaephon
quelle
$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).Exits mit Status 1 für mich.
Contrebis
1
Ja, es wird auch für mich mit Status 1 beendet. Aber auch so cptut kopieren Sie die entsprechenden Dateien dir1/*auf jedem System , das ich überprüfte: Arch Linux, Ubuntu 14.04, OpenBSD 3.9 und 5.5, SuSE Linux 8.1, FreeBSD 6.2, Solaris 8, 9 und 10 (wo cpeigentlich Ausfahrten mit dem Code 2). Dieses Verhalten ist also weder neu (SuSE 8.1 stammt aus dem Jahr 2002) noch auf Linux beschränkt. cpBeendet mit einem Exit-Code ungleich Null, weil er nicht alles tun konnte, was ihm gesagt wurde. Das heißt nicht, dass es nichts tut .
Adaephon
3
Klar, ich dachte, es ist erwähnenswert, denn wenn Sie Befehle damit verketten, &&kann dies zu Problemen führen. Ich habe versucht, so etwas zu tun, obwohl ich mich jetzt nicht an den Kontext erinnern kann.
Contrebis
Dies kopiert keine versteckten Dateien.
felwithe
@felwithe Ob *versteckte Dateien enthalten sind oder wie versteckte Dateien eingeschlossen werden sollen, hängt von der Shell ab. Wenn das *keine versteckten Dateien enthält, können Sie sie mit abgleichen .*. Beachten Sie, dass dies .and ..on bashund dashaber nicht on einschließt zsh. Im Rahmen dieser Antwort können Sie mit cp dir1/* dir1/.* dir2weil durchkommen .und ..sind Verzeichnisse und werden nicht kopiert. zshkann auch dazu gebracht werden, versteckte Dateien mit einzuschließen *(D).
Adaephon
6

Es ist die Shell, die Platzhalter erweitert, nicht die Befehle. Erweitert also cp dir1/* dir2/*zuerst die beiden Platzhalter und ruft dann cpdas Ergebnis auf. Dies ist anscheinend überhaupt nicht das, was Sie anscheinend erwarten: Je nachdem, wie viele Dateien bereits vorhanden sind dir2, dir2/*kann dies zu einem oder mehreren Argumenten führen. Der Befehl cpweiß nicht, welches seiner Argumente aus der Erweiterung des ersten Musters und welches aus der Erweiterung des zweiten Musters stammt. Es wird erwartet, dass das letzte Argument der Name des Zielverzeichnisses ist. Um alle Dateien aus dem Verzeichnis dir1in das Verzeichnis zu kopieren dir2, muss das letzte Argument das Verzeichnis sein dir2:

cp dir1/* dir2

Da *alle Dateien übereinstimmen, wird cpversucht, alle Dateien zu kopieren. Dies schließt Verzeichnisse ein: Verzeichnisse sind auch Dateien. Verzeichnisse werden übersprungen, es wird jedoch ein Fehler gemeldet. Es kopiert den Inhalt spezieller Dateien wie Named Pipes (etwas sollte besser in sie geschrieben werden oder cpblockiert) usw.

Um nur reguläre Dateien zu kopieren , müssen Sie den Abgleich einschränken. In zsh können Sie dafür das Glob-Qualifikationsmerkmal verwenden . :

cp dir1/*(.) dir2

Andere Muscheln haben das nicht. Mit dem findBefehl können Sie nach Dateitypen filtern. Angenommen, Sie verwenden nicht eingebettetes Linux oder Cygwin:

find dir1 -maxdepth 1 -type f -exec cp -t dir2 {} +

Unter Linux, FreeBSD und OSX:

find dir1 -maxdepth 1 -type f | xargs -I {} cp {} dir2
Gilles 'SO - hör auf böse zu sein'
quelle
Gibt es einen Grund zu spezifizieren -maxdepth 1. Gibt es auch eine Möglichkeit, die ursprüngliche Verzeichnishierarchie im Zielverzeichnis rekursiv zu kopieren und beizubehalten?
Abdull
@Abdull Ohne würde -maxdepth 1der findBefehl in Unterverzeichnisse zurückkehren, was hier nicht erwünscht war. Wenn Sie den gesamten Verzeichnisbaum einschließlich der Unterverzeichnisse kopieren möchten, ist dies eine völlig andere Frage, und die Antwort ist viel einfacher : cp -a dir1 dir2.
Gilles 'SO - hör auf böse zu sein'
0

Unten finden Sie den Befehl zum Kopieren der Datei vom Quell- in das Zielverzeichnis.

  1. Gehen Sie zum Quellordner und schreiben Sie den folgenden Befehl:

    $ cp fileName destination directory path

Beispiel:

cp publichOT.sh  /data/home/useradmin
Tapan Dubey
quelle