Ответы:
mv
перемещает файл и ln -s
создает символическую ссылку, поэтому основная задача выполняется с помощью сценария, который выполняет эти две команды:
#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
Есть несколько предостережений. Если вторым аргументом является каталог, тогда mv
файл будет перемещен в этот каталог, но ln -s
будет создана ссылка на каталог, а не на перемещенный файл.
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"
Другое предостережение заключается в том, что первым аргументом ln -s
является точный текст символической ссылки. Это относительно местоположения цели, а не каталога, в котором выполняется команда. Если исходное местоположение отсутствует в текущем каталоге, а цель не указана абсолютным путем, ссылка будет неверной. В этом случае путь необходимо переписать. В этом случае я создам абсолютную ссылку (относительная ссылка была бы предпочтительнее, но ее сложнее получить правильно). Этот сценарий предполагает, что у вас нет имен файлов, заканчивающихся символом новой строки.
#!/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"
Если у вас есть несколько файлов, обрабатывайте их в цикле.
#!/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
может быть более информативным для пользователей, которые переносят большой файл с диска, что может занять некоторое время.
Поместите это в файл .sh и сделайте его исполняемым ( chmod +x filename
):
#!/bin/bash
mv "$1" "$2"
ln -s "$2" "$1"
Пример использования:
./test.sh asdf otherdir/asdf
Обратите внимание, что это не проверяет безопасность и т. Д. В зависимости от сложности вашей задачи, этого может быть достаточно.
./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf
. *
Не кажется, работает с вашим test.sh
. У вас есть обходной путь? Thx
Я обычно использую эту однострочную функцию:
function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }
Использование похоже на mv или cp:
ml old_file target_dir/new_file_name
Разбивая это:
mkdir -p "$(dirname "$1")"
- создать каталог назначения, если он еще не существует
dirname "$1"
- получить каталог компонента пути (убрать имя файла)rsync -aP --no-links "$1" "$2"
- скопируйте файл в место назначения. Замените это, mv "$1" "$2"
если оба файла находятся в одной файловой системе для лучшей производительности.
-a
- сохранить право собственности и все другие разрешения. Вы можете настроить это, чтобы сохранить только те компоненты, которые вы хотите.-P
- показать прогресс.--no-links
- не копировать ссылки - это означает, что вы можете запускать эту команду столько раз, сколько захотите для одного и того же файла, и вы никогда не потеряете свой файл, случайно перезаписав файл назначения символической ссылкой на себя.ln -sf "$2" "$1"
- перезаписать старый файл символической ссылкой на новый файл
-s
- используйте символические ссылки-f
- перезаписать старый файл