Risposte:
mv
sposta un file e ln -s
crea un collegamento simbolico, quindi l'attività di base viene eseguita da uno script che esegue questi due comandi:
#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
Ci sono alcuni avvertimenti. Se il secondo argomento è una directory, mv
il file verrà spostato in quella directory, ma ln -s
verrà creato un collegamento alla directory anziché al file spostato.
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"
Un altro avvertimento è che il primo argomento ln -s
è il testo esatto del collegamento simbolico. È relativo alla posizione della destinazione, non alla directory in cui viene eseguito il comando. Se la posizione originale non si trova nella directory corrente e la destinazione non è espressa da un percorso assoluto, il collegamento sarà errato. In questo caso, il percorso deve essere riscritto. In questo caso, creerò un collegamento assoluto (sarebbe preferibile un collegamento relativo, ma è più difficile ottenere il giusto). Questo script presuppone che non si disponga di nomi di file che terminano con un carattere di nuova riga.
#!/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 hai più file, elaborali in un ciclo.
#!/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
potrebbe essere più informativo per gli utenti che stanno spostando un file di grandi dimensioni da un disco, il che potrebbe richiedere del tempo.
Mettilo nel file .sh e rendilo eseguibile ( chmod +x filename
):
#!/bin/bash
mv "$1" "$2"
ln -s "$2" "$1"
Esempio di utilizzo:
./test.sh asdf otherdir/asdf
Si noti che ciò non comporta controlli di sicurezza, ecc. A seconda di quanto sia complessa l'attività, ciò potrebbe essere sufficiente.
./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf
. Il *
non sembra di lavorare con il vostro test.sh
. Hai una soluzione? Grazie
In genere utilizzo questa funzione a una riga:
function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }
L'utilizzo è simile a mv o cp:
ml old_file target_dir/new_file_name
Abbattendo:
mkdir -p "$(dirname "$1")"
- crea la directory di destinazione se non esiste già
dirname "$1"
- ottieni il componente directory del percorso (elimina il nome file)rsync -aP --no-links "$1" "$2"
- copia il file sulla destinazione. Sostituiscilo con mv "$1" "$2"
se entrambi i file si trovano sullo stesso filesystem per prestazioni migliori.
-a
- preservare la proprietà e tutte le altre autorizzazioni. È possibile ottimizzare questo per preservare solo i componenti desiderati.-P
- mostra progressi.--no-links
- non copiare i collegamenti - questo significa che puoi eseguire questo comando tutte le volte che vuoi sullo stesso file e non perderai mai il tuo file sovrascrivendo accidentalmente il tuo file di destinazione con un link simbolico a se stesso.ln -sf "$2" "$1"
- sovrascrive il vecchio file con un link simbolico al nuovo file
-s
- usa collegamenti simbolici-f
- sovrascrive il vecchio file