Ainda não é exatamente um forro, mas você se aproxima com uma única chamada para perl juntamente com sua poderosa opção e
(ou seja, executar a parte de substituição):
backup(){
mv "$1" "$(echo $1 |perl -pe '~s|(.*?)(~([0-9]*)~)?$|print "$1~".(${3}+1)."~"|e and exit')"
}
Observe o and exit
que impede que o perl imprima a contagem correspondente que, de outra forma, polui o nome.
Você também pode adicionar 2>/dev/null
ao final da linha para mantê-lo quieto quando o arquivo não existir.