Odpowiedzi:
mvprzenosi plik i ln -stworzy dowiązanie symboliczne, więc podstawowe zadanie wykonuje skrypt, który wykonuje te dwa polecenia:
#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
Jest kilka zastrzeżeń. Jeśli drugim argumentem jest katalog, mvprzenosi plik do tego katalogu, ale ln -stworzy łącze do katalogu, a nie do przeniesionego pliku.
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"
Innym zastrzeżeniem jest to, że pierwszym argumentem ln -sjest dokładny tekst dowiązania symbolicznego. Jest to zależne od położenia celu, a nie katalogu, w którym polecenie jest wykonywane. Jeśli oryginalnej lokalizacji nie ma w bieżącym katalogu, a cel nie jest wyrażony przez ścieżkę bezwzględną, link będzie niepoprawny. W takim przypadku ścieżka musi zostać przepisana. W takim przypadku utworzę link bezwzględny (preferowany byłby link względny, ale trudniej jest go poprawnie uzyskać). Ten skrypt zakłada, że nie masz nazw plików, które kończą się znakiem nowej linii.
#!/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"
Jeśli masz wiele plików, przetwarzaj je w pętli.
#!/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-filesmoże być bardziej pouczająca dla użytkowników, którzy przenoszą duży plik z dysku, co może zająć trochę czasu.
Umieść to w pliku .sh i uczyń go wykonywalnym ( chmod +x filename):
#!/bin/bash
mv "$1" "$2"
ln -s "$2" "$1"
Przykład użycia:
./test.sh asdf otherdir/asdf
Pamiętaj, że nie wymaga to kontroli bezpieczeństwa itp. W zależności od stopnia złożoności zadania może to być wystarczające.
./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf. *Nie wydają się być pracy z test.sh. Czy masz obejście? Thx
Ogólnie używam tej funkcji jednowierszowej:
function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }
Użycie jest podobne do mv lub cp:
ml old_file target_dir/new_file_name
Podział:
mkdir -p "$(dirname "$1")" - utwórz katalog docelowy, jeśli jeszcze nie istnieje
dirname "$1" - pobierz komponent katalogu ścieżki (usuń nazwę pliku)rsync -aP --no-links "$1" "$2"- skopiuj plik do miejsca docelowego. Zastąp to, mv "$1" "$2"jeśli oba pliki znajdują się w tym samym systemie plików, aby uzyskać lepszą wydajność.
-a- zachować własność i wszystkie inne uprawnienia. Możesz to dostroić, aby zachować tylko te elementy, które chcesz.-P - pokaż postęp.--no-links - nie kopiuj linków - oznacza to, że możesz uruchomić tę komendę tyle razy, ile chcesz na tym samym pliku, i nigdy nie stracisz pliku, przypadkowo zastępując plik docelowy dowiązaniem symbolicznym do siebie.ln -sf "$2" "$1" - nadpisz stary plik dowiązaniem symbolicznym do nowego pliku
-s - używaj dowiązań symbolicznych-f - nadpisz stary plik