Respostas:
mv
move um arquivo e ln -s
cria um link simbólico; portanto, 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, mv
o arquivo será movido para esse diretório, mas ln -s
criará um link para o diretório, e não 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 à localização do destino, não ao diretório em que 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 de acertar). Este script pressupõe que você não possui nomes de arquivos 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
rsync --remove-source-files
pode ser mais informativo para os usuários que estão movendo um arquivo grande de um disco, o que pode levar algum tempo.
Coloque isso no arquivo .sh e torne-o executável ( chmod +x filename
):
#!/bin/bash
mv "$1" "$2"
ln -s "$2" "$1"
Exemplo de uso:
./test.sh asdf otherdir/asdf
Observe que isso não faz verificações de segurança, etc. Dependendo da complexidade da sua tarefa, isso pode ser suficiente.
./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf
. A *
não parece estar a trabalhar com o seutest.sh
. Você tem uma solução alternativa? Thx
Eu geralmente uso a função de uma linha:
function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }
O uso é semelhante ao mv ou cp:
ml old_file target_dir/new_file_name
Dividindo:
mkdir -p "$(dirname "$1")"
- crie o diretório de destino se ele ainda não existir
dirname "$1"
- obtém o componente de diretório do caminho (retira o nome do arquivo)rsync -aP --no-links "$1" "$2"
- copie o arquivo para o destino. Substitua por mv "$1" "$2"
se os dois arquivos estiverem no mesmo sistema de arquivos para obter melhor desempenho.
-a
- preservar a propriedade e todas as outras permissões. Você pode ajustar isso para preservar apenas os componentes que deseja.-P
- mostrar progresso.--no-links
- não copie links - isso significa que você pode executar este comando quantas vezes quiser no mesmo arquivo e nunca perderá o arquivo substituindo acidentalmente o arquivo de destino com um link simbólico.ln -sf "$2" "$1"
- sobrescreva o arquivo antigo com um link simbólico para o novo arquivo
-s
- use links simbólicos-f
- sobrescrever o arquivo antigo