mv
move um arquivo e ln -s
cria um link simbólico, então a tarefa básica é realizada por um script que executa esses dois comandos:
#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
Existem algumas ressalvas. Se o segundo argumento for um diretório, então mv
moverá o arquivo para esse diretório, mas ln -s
criaria um link para o diretório em vez de para o arquivo movido.
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"
Outra ressalva é que o primeiro argumento para ln -s
é o texto exato do link simbólico. É relativo ao local do alvo, não ao diretório onde o comando é executado. Se o local original não estiver no diretório atual e o destino não for expresso por um caminho absoluto, o link estará incorreto. Nesse caso, o caminho precisa ser reescrito. Nesse caso, criarei um link absoluto (um link relativo seria preferível, mas é mais difícil acertar). Este script assume que você não tem nomes de arquivo que terminam em um caractere de nova linha.
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
case "$original" in
*/*)
case "$target" in
/*) :;;
*) target="$(cd -- "$(dirname -- "$target")" && pwd)/${target##*/}"
esac
esac
ln -s -- "$target" "$original"
Se você tiver vários arquivos, processe-os em um loop.
#!/bin/sh
while [ $# -gt 1 ]; do
eval "target=\${$#}"
original="$1"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
case "$original" in
*/*)
case "$target" in
/*) :;;
*) target="$(cd -- "$(dirname -- "$target")" && pwd)/${target##*/}"
esac
esac
ln -s -- "$target" "$original"
shift
done