移动文件并用符号链接替换它

Yo *_* B. 19 shell-script files ln mv

有人可以给我一个命令:

  • 将文件移至新目录
  • 并在旧位置留下一个符号链接到新位置

Gil*_*il' 25

mv移动一个文件,并ln -s创建一个符号链接,所以基本任务是由执行这两个命令的脚本完成的:

#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
Run Code Online (Sandbox Code Playgroud)

有一些注意事项。如果第二个参数是一个目录,那么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"
Run Code Online (Sandbox Code Playgroud)

另一个警告是第一个参数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"
Run Code Online (Sandbox Code Playgroud)

如果您有多个文件,请循环处理它们。

#!/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
Run Code Online (Sandbox Code Playgroud)