Uso:
$ copy() { mkdir -p -- "${@: -1}" && cp -- "$@" ; }
$ copy * ../b/c/d/
Nota: funciona com o bash, ksh93 e zsh.
"${@: -1}"
corresponde ao ${parameter:offset}
form: todos os parâmetros que começam no deslocamento. O offset -1 corresponde ao último parâmetro, já que os offsets negativos contam a partir do final. O espaço é necessário, caso contrário, seria a forma ${parameter:-word}
. Veja o manual bash para mais informações.
"$@"
expande para a lista de parâmetros, o que é desejado para cp
.
Nota 2: Como sugerido por mikeserv, você pode usar
eval 'mkdir -p -- "${'"$#"'}"'
que é mais portátil (POSIX), em vez de
mkdir -p -- "${@: -1}"
Em relação ao desempenho, a solução eval
é muito mais rápida com o bash 4.3.30, mas a outra solução é mais rápida com o ksh 93u + e o zsh 5.0.6 (o ksh93 e o zsh são muito mais rápidos que o bash nos dois casos); e o dash 5.7 com a solução eval
(o outro não é suportado) é um pouco mais rápido que o ksh93 com a solução "${@: -1}"
. Portanto, dependendo do seu caso (script, uso interativo, suporte para recursos de shell específicos, etc.), faça sua escolha ... Observe, entretanto, que no contexto de cp
(que levará a maior parte do tempo), esse desempenho diferenças não serão perceptíveis.
O script que usei para o teste:
i=50000
while [ $i -ne 0 ];
do
# : "${@: -1}"
eval ': "${'"$#"'}"'
i=$((i-1))
done
(comente a linha eval
e descomente a linha anterior para a outra solução), chamada com:
time sh ./tst 'seq 1000'
time bash ./tst 'seq 1000'
time ksh93 ./tst 'seq 1000'
time zsh ./tst 'seq 1000'