Copiar vários arquivos e criar os diretórios de destino ao mesmo tempo?

Copiar vários arquivos e criar os diretórios de destino ao mesmo tempo?

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 x1estão x2ordenados 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 evalsoluçã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 evalsoluçã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 evallinha 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 tarresolver! 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, tartodas as (sub)pastas serão criadas automaticamente para você! Melhor,

Nabi

informação relacionada