Ich möchte einen Befehl (oder wahrscheinlich eine Option für cp), der das Zielverzeichnis erstellt, wenn es nicht existiert.
Beispiel:
cp -? file /path/to/copy/file/to/is/very/deep/there
Ich möchte einen Befehl (oder wahrscheinlich eine Option für cp), der das Zielverzeichnis erstellt, wenn es nicht existiert.
Beispiel:
cp -? file /path/to/copy/file/to/is/very/deep/there
Ich glaube nicht, dass Sie die test -d
: mkdir -p
ist auch dann erfolgreich, wenn das Verzeichnis bereits existiert.
Oops, richtig. Aber dann kann test ein Bash-Builtin sein (besonders wenn es als [[ -d "$d" ]] geschrieben wird) und mkdir nicht ;-)
Wenn beide der folgenden Punkte zutreffen:
cp
(und nicht zum Beispiel die Mac-Version), unddann können Sie dies mit dem --parents
Flagge von cp
. Von der Infoseite (einsehbar unter http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html#cp-invocation oder mit info cp
o man cp
) :
--parents Form the name of each destination file by appending to the target directory a slash and the specified name of the source file. The last argument given to `cp' must be the name of an existing directory. For example, the command: cp --parents a/b/c existing_dir copies the file `a/b/c' to `existing_dir/a/b/c', creating any missing intermediate directories.
Beispiel:
/tmp $ mkdir foo
/tmp $ mkdir foo/foo
/tmp $ touch foo/foo/foo.txt
/tmp $ mkdir bar
/tmp $ cp --parents foo/foo/foo.txt bar
/tmp $ ls bar/foo/foo
foo.txt
Ich würde sagen, gnu-spezifisch. Wenn Sie macports
können Sie die coreutils und ihre gcp
.
Zum Kopieren myfile.txt
a /foo/bar/myfile.txt
verwenden:
mkdir -p /foo/bar && cp myfile.txt $_
Da dies aus mehreren Komponenten besteht, werde ich die gesamte Syntax Schritt für Schritt erläutern.
Le site mkdir Nutzen, wie im POSIX-Standard festgelegt , macht Verzeichnisse. Die -p
Argument, wie in der Dokumentation beschrieben, bewirkt mkdir zu
Erstellen Sie alle fehlenden Zwischenpfadkomponenten
was bedeutet, dass beim Aufruf von mkdir -p /foo/bar
, mkdir wird erstellt /foo
und /foo/bar
si /foo
nicht bereits vorhanden ist. (Ohne -p
wird stattdessen ein Fehler ausgegeben.
Le site &&
Listenoperator, wie in der Dokumentation POSIX-Standard (oder die Bash-Handbuch wenn Sie das bevorzugen), hat den Effekt, dass cp myfile.txt $_
wird nur ausgeführt, wenn mkdir -p /foo/bar
wird erfolgreich ausgeführt. Dies bedeutet, dass die cp
Befehl wird nicht versucht auszuführen, wenn mkdir
versagt bei einer der vielen Gründe, warum es scheitern könnte .
Schließlich ist die $_
übergeben wir als zweites Argument an cp
ist ein "spezieller Parameter", der nützlich sein kann, um die Wiederholung langer Argumente (wie Dateipfade) zu vermeiden, ohne sie in einer Variablen speichern zu müssen. Per das Bash-Handbuch , it:
wird auf das letzte Argument des vorherigen Befehls erweitert
In diesem Fall ist das die /foo/bar
haben wir an mkdir
. Also die cp
wird der Befehl erweitert zu cp myfile.txt /foo/bar
, die Kopien myfile.txt
in die neu erstellte /foo/bar
Verzeichnis.
Beachten Sie, dass $_
es no Teil des POSIX-Standards so dass theoretisch eine Unix-Variante eine Shell haben könnte, die dieses Konstrukt nicht unterstützt. Ich kenne jedoch keine modernen Shells, die dieses Konstrukt nicht unterstützen. $_
Bash, Dash und zsh tun dies auf jeden Fall.
Ein letzter Hinweis: Der Befehl, den ich am Anfang dieser Antwort gegeben habe, setzt voraus, dass Ihre Verzeichnisnamen keine Leerzeichen enthalten. Wenn Sie es mit Namen mit Leerzeichen zu tun haben, müssen Sie diese in Anführungszeichen setzen, damit die verschiedenen Wörter nicht als unterschiedliche Argumente für mkdir
o cp
. Ihr Befehl würde also wie folgt aussehen:
mkdir -p "/my directory/name with/spaces" && cp "my filename with spaces.txt" "$_"
Nebenbei bemerkt: Ich bin normalerweise enttäuscht über den Mangel an Details in Fragen über Bash- oder Unix-Shell-Befehle auf Stack Overflow, die oft einen komplizierten und extrem dichten Einzeiler ausgeben, der schwer zu entschlüsseln ist, wenn man nicht bereits ein Unix-Experte ist. Ich habe versucht, hier das entgegengesetzte Extrem zu wählen und sowohl jedes Detail der Syntax zu erklären als auch auf die entsprechenden Stellen zu verlinken, an denen man Dokumentation darüber findet, wie dieses Zeug funktioniert. Ich hoffe, das hilft wenigstens einigen Leuten. Außerdem, Ehre, wem Ehre gebührt: Ich habe diesen Ansatz von dieser Antwort auf eine doppelte Frage geklaut: stackoverflow.com/a/14085147/1709587
Ich habe $_ noch nie gesehen. Worauf bezieht es sich? auf den im letzten Befehl verwendeten Ordner?
@thebunnyrules Aber... aber... es gibt eine "Wie funktioniert das?" Abschnitt in meiner Antwort, der buchstäblich mehrere Absätze enthält, die speziell der Frage gewidmet sind, die Sie gerade gestellt haben. Ich fühle mich ignoriert und ungeliebt :(
Das ist eine alte Frage, aber vielleicht kann ich eine alternative Lösung vorschlagen.
Sie können die install
Programm, um Ihre Datei zu kopieren und den Zielpfad "on the fly" zu erstellen.
install -D file /path/to/copy/file/to/is/very/deep/there/file
Es gibt jedoch einige Aspekte, die zu beachten sind:
Sie können die #2 leicht ändern, indem Sie die -m
um die Berechtigungen für die Zieldatei festzulegen (Beispiel: -m 664
erstellt die Zieldatei mit den Rechten rw-rw-r--
genauso wie das Erstellen einer neuen Datei mit touch
).
Und hier ist sie die schamloser Link zu der Antwort, die mich inspiriert hat \=)
Beachten Sie, dass dieser Befehl die Zieldateien mit 755
( rwxr-xr-x
), was wahrscheinlich nicht erwünscht ist. Sie können etwas anderes mit der Option -m
Schalter, aber ich konnte keine Möglichkeit finden, einfach behalten. die Dateiberechtigungen :(
@Kalmi, um richtig zu zitieren, sollten Sie auch zitieren $2
als Argument für dirname
. Wie mkdir -p "$(dirname "$2")"
. Ohne diese Anführung $2
en cp
ist nutzlos ;)
Beachten Sie, dass diese Antwort davon ausgeht, dass $2 nicht bereits das Zielverzeichnis ist, andernfalls würden Sie einfach "mkdir -p "$2" && cp "$1" "$2" als Funktionskörper verwenden
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
0 Stimmen
縡 Wie man den cp-Befehl alle notwendigen Ordner für das Kopieren einer Datei an einen Zielort erstellen lässt
9 Stimmen
Die akzeptierte Antwort ist falsch (es gibt eine solche Option für cp). Siehe zweite Antwort von Paul Whipp.
1 Stimmen
@Ronenz, ich stimme zu, dass es eine erwähnenswerte Option in GNU gibt
cp
(wie von Paul Whipp beantwortet), aber es ist nicht so allgemein, wie es der OP wollte. Sie kann kopierena/foo/bar/file
までb/foo/bar/file
aber er kann nicht kopierenfile
までb/foo/bar/file
. (d. h. es funktioniert nur, um übergeordnete Verzeichnisse zu erstellen, die im Fall der ersten Datei bereits vorhanden waren, aber es kann keine beliebigen Verzeichnisse erstellen)3 Stimmen
Das sieht nach einem netten Feature-Wunsch für cp aus. Besteht die Möglichkeit, dass wir in naher Zukunft einen solchen Befehlszeilenschalter bekommen?
0 Stimmen
Die akzeptierte Antwort ist teilweise richtig und die zweite Antwort gibt Ihnen diese Möglichkeit nicht. Die Probleme liegen bei
mkdir
Teil. Wie man es im Inneren implementiertcp
Befehl.