
Я читаюКак можно скопировать файл и одновременно создать целевые каталоги?
Но это решение работает только если вы хотите скопироватьодинфайл.
Как скопировать несколько файлов в каталог, который еще не существует, и автоматически создать его с помощью одной команды?
например:
cd /tmp/
mkdir a/
cd a/
touch x1 x2
cp --magic * ../b/c/d/
Итак, в итоге два файла x1
упорядочены x2
следующим образом:
/tmp/b/c/d/x1
/tmp/b/c/d/x2
решение1
Использовать:
$ copy() { mkdir -p -- "${@: -1}" && cp -- "$@" ; }
$ copy * ../b/c/d/
Примечание: работает с bash, ksh93 и zsh.
"${@: -1}"
соответствует форме ${parameter:offset}
: все параметры, начиная со смещения. Смещение -1 соответствует последнему параметру, так как отрицательные смещения отсчитываются с конца. Пробел необходим, иначе это была бы форма ${parameter:-word}
. Подробнее см. в руководстве по bash.
"$@"
расширяется до списка параметров, что и требуется cp
.
Примечание 2: Как предлагает mikeserv, вы можете использовать
eval 'mkdir -p -- "${'"$#"'}"'
который более переносим (POSIX), вместо
mkdir -p -- "${@: -1}"
Что касается производительности, eval
решение намного быстрее с bash 4.3.30, но другое решение быстрее с ksh 93u+ и zsh 5.0.6 (ksh93 и zsh намного быстрее, чем bash в обоих случаях); и dash 5.7 с решением eval
(другое не поддерживается) немного быстрее, чем ksh93 с "${@: -1}"
решением. Так что, в зависимости от вашего случая (скрипт, интерактивное использование, поддержка определенных функций оболочки и т. д.), сделайте свой выбор... Однако обратите внимание, что в контексте cp
(который займет большую часть времени) эти различия в производительности не будут заметны.
Скрипт, который я использовал для теста:
i=50000
while [ $i -ne 0 ];
do
# : "${@: -1}"
eval ': "${'"$#"'}"'
i=$((i-1))
done
(закомментируйте eval
строку и раскомментируйте предыдущую строку для другого решения), вызывается с помощью:
time sh ./tst `seq 1000`
time bash ./tst `seq 1000`
time ksh93 ./tst `seq 1000`
time zsh ./tst `seq 1000`
решение2
У меня была такая же проблема и я tar
ее решил! Вот так:
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"
В этом случае tar
автоматически создаст все (под)папки для вас! Лучше всего,
Наби