
ich leseWie kann ich eine Datei kopieren und gleichzeitig die Zielverzeichnisse erstellen?
Aber die Lösung dort funktioniert nur, wenn Sie kopieren möchteneinsDatei.
Wie kopiere ich mehrere Dateien in ein Verzeichnis, das noch nicht existiert, und erstelle es mit einem Befehl automatisch?
Zum Beispiel:
cd /tmp/
mkdir a/
cd a/
touch x1 x2
cp --magic * ../b/c/d/
x1
Die beiden Dateien sind also am Ende x2
folgendermaßen angeordnet:
/tmp/b/c/d/x1
/tmp/b/c/d/x2
Antwort1
Verwenden:
$ copy() { mkdir -p -- "${@: -1}" && cp -- "$@" ; }
$ copy * ../b/c/d/
Hinweis: Es funktioniert mit Bash, KSH93 und ZSH.
"${@: -1}"
entspricht der ${parameter:offset}
Form: alle Parameter beginnend beim Offset. Der Offset -1 entspricht dem letzten Parameter, da negative Offsets vom Ende her zählen. Das Leerzeichen ist notwendig, sonst wäre es die ${parameter:-word}
Form. Weitere Informationen finden Sie im Bash-Handbuch.
"$@"
erweitert sich zur Parameterliste, was gewünscht ist cp
.
Hinweis 2: Wie von mikeserv vorgeschlagen, können Sie
eval 'mkdir -p -- "${'"$#"'}"'
das portabler ist (POSIX), statt
mkdir -p -- "${@: -1}"
In Bezug auf die Leistung eval
ist die Lösung mit Bash 4.3.30 viel schneller, aber die andere Lösung ist mit Ksh 93u+ und Zsh 5.0.6 schneller (Ksh93 und Zsh sind in beiden Fällen viel schneller als Bash); und Dash 5.7 mit der eval
Lösung (die andere wird nicht unterstützt) ist etwas schneller als Ksh93 mit der "${@: -1}"
Lösung. Treffen Sie also Ihre Wahl je nach Ihrem Fall (Skript, interaktive Verwendung, Unterstützung für bestimmte Shell-Funktionen usw.) ... Beachten Sie jedoch, dass diese Leistungsunterschiede im Kontext von cp
(was die meiste Zeit in Anspruch nehmen wird) nicht spürbar sind.
Das Skript, das ich für den Test verwendet habe:
i=50000
while [ $i -ne 0 ];
do
# : "${@: -1}"
eval ': "${'"$#"'}"'
i=$((i-1))
done
(Kommentieren Sie die eval
Zeile aus und entfernen Sie die Kommentarzeichen aus der vorherigen Zeile für die andere Lösung), aufgerufen mit:
time sh ./tst `seq 1000`
time bash ./tst `seq 1000`
time ksh93 ./tst `seq 1000`
time zsh ./tst `seq 1000`
Antwort2
Ich hatte dasselbe Problem und habe tar
es folgendermaßen gelöst:
tmpfile=/tmp/myfile.tar
files="/some/folder/file1.txt /some/other/folder/file2.txt"
targetfolder=/home/you/somefolder
tar --file="$tmpfile" "$files"
tar --extract --file="$tmpfile" --directory="$targetfolder"
In diesem Fall tar
werden automatisch alle (Unter-)Ordner für Sie erstellt! Beste Grüße,
Nabi