Réponses:
mv
déplace un fichier et ln -s
crée un lien symbolique, de sorte que la tâche de base est accomplie par un script qui exécute ces deux commandes:
#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
Il y a quelques mises en garde. Si le deuxième argument est un répertoire, il mv
déplacerait le fichier dans ce répertoire, mais ln -s
créerait un lien vers le répertoire plutôt que vers le fichier déplacé.
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"
Une autre mise en garde est que le premier argument de ln -s
est le texte exact du lien symbolique. C'est relatif à l'emplacement de la cible, pas au répertoire où la commande est exécutée. Si l'emplacement d'origine ne se trouve pas dans le répertoire en cours et que la cible n'est pas exprimée par un chemin absolu, le lien sera incorrect. Dans ce cas, le chemin doit être réécrit. Dans ce cas, je vais créer un lien absolu (un lien relatif serait préférable, mais il est plus difficile de bien faire les choses). Ce script suppose que vous n'avez pas de noms de fichiers se terminant par un caractère de nouvelle ligne.
#!/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"
Si vous avez plusieurs fichiers, traitez-les en boucle.
#!/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
pourrait être plus informatif pour les utilisateurs qui déplacent un gros fichier d'un disque, ce qui peut prendre un certain temps.
Mettez-le dans un fichier .sh et rendez-le exécutable ( chmod +x filename
):
#!/bin/bash
mv "$1" "$2"
ln -s "$2" "$1"
Exemple d'utilisation:
./test.sh asdf otherdir/asdf
Notez que cela ne fait aucun contrôle de sécurité, etc. Selon la complexité de votre tâche, cela peut être suffisant.
./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf
. Le *
ne semble pas fonctionner avec votre test.sh
. Avez-vous une solution de contournement? Thx
J'utilise généralement la fonction cette ligne:
function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }
L'utilisation est similaire à mv ou cp:
ml old_file target_dir/new_file_name
Décomposer:
mkdir -p "$(dirname "$1")"
- créer le répertoire de destination s'il n'existe pas déjà
dirname "$1"
- récupérer le composant répertoire du chemin (supprimer le nom du fichier)rsync -aP --no-links "$1" "$2"
- copiez le fichier vers la destination. Remplacez-le par mv "$1" "$2"
si les deux fichiers se trouvent sur le même système de fichiers pour de meilleures performances.
-a
- conserver la propriété et toutes les autres autorisations. Vous pouvez régler cela pour ne conserver que les composants souhaités.-P
- montrer les progrès.--no-links
- ne copiez pas les liens - cela signifie que vous pouvez exécuter cette commande autant de fois que vous le souhaitez sur le même fichier, et vous ne perdrez jamais votre fichier en écrasant accidentellement votre fichier de destination avec un lien symbolique vers lui-même.ln -sf "$2" "$1"
- écraser l'ancien fichier avec un lien symbolique vers le nouveau fichier
-s
- utiliser des liens symboliques-f
- écraser l'ancien fichier