
Eu leioComo posso copiar um arquivo e criar os diretórios de destino ao mesmo tempo?
Mas a solução aí só funciona se você quiser copiarumarquivo.
Como eu copiaria vários arquivos em um diretório que ainda não existe e os criaria automaticamente com um comando?
por exemplo:
cd /tmp/
mkdir a/
cd a/
touch x1 x2
cp --magic * ../b/c/d/
então no final os dois arquivos x1
estão x2
ordenados assim:
/tmp/b/c/d/x1
/tmp/b/c/d/x2
Responder1
Usar:
$ copy() { mkdir -p -- "${@: -1}" && cp -- "$@" ; }
$ copy * ../b/c/d/
Nota: funciona com bash, ksh93 e zsh.
"${@: -1}"
corresponde ao ${parameter:offset}
formato: todos os parâmetros começando no deslocamento. O deslocamento -1 corresponde ao último parâmetro, pois os deslocamentos negativos contam a partir do final. O espaço é necessário, caso contrário seria a ${parameter:-word}
forma. Consulte o manual do bash para obter mais informações.
"$@"
expande para a lista de parâmetros, que é o que se deseja cp
.
Nota 2: Conforme sugerido por mikeserv, você pode usar
eval 'mkdir -p -- "${'"$#"'}"'
que é mais portátil (POSIX), em vez de
mkdir -p -- "${@: -1}"
Quanto ao desempenho, a eval
solução é muito mais rápida com o bash 4.3.30, mas a outra solução é mais rápida com ksh 93u+ e zsh 5.0.6 (ksh93 e zsh sendo muito mais rápidos que bash em ambos os casos); e o traço 5.7 com a eval
solução (o outro não é suportado) é um pouco mais rápido que o ksh93 com a "${@: -1}"
solução. Portanto, dependendo do seu caso (script, uso interativo, suporte para recursos específicos do shell, etc.), faça sua escolha... Observe, entretanto, que no contexto de cp
(que levará a maior parte do tempo), essas diferenças de desempenho vencerão. não seja perceptível.
O script que usei para o teste:
i=50000
while [ $i -ne 0 ];
do
# : "${@: -1}"
eval ': "${'"$#"'}"'
i=$((i-1))
done
(comente a eval
linha e descomente a linha anterior para a outra solução), chamado com:
time sh ./tst `seq 1000`
time bash ./tst `seq 1000`
time ksh93 ./tst `seq 1000`
time zsh ./tst `seq 1000`
Responder2
Eu tive esse mesmo problema e resolvi tar
resolver! Igual a:
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"
Neste caso, tar
todas as (sub)pastas serão criadas automaticamente para você! Melhor,
Nabi