web-dev-qa-db-ja.com

ファイルを移動してシンボリックリンクで置き換えます

誰かが私に次のようなコマンドを与えることができますか?

  • ファイルを新しいディレクトリに移動する
  • 古い場所にあるシンボリックリンクを新しい場所に残します
16
Yo B.

mvはファイルを移動し、ln -sはシンボリックリンクを作成するため、次の2つのコマンドを実行するスクリプトによって基本的なタスクが実行されます。

#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"

いくつかの注意点があります。 2番目の引数がディレクトリの場合、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"

もう1つの注意点は、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

これを.shファイルに入れて、実行可能にします(chmod +x filename):

#!/bin/bash

mv "$1" "$2"
ln -s "$2" "$1"

使用例:

./test.sh asdf otherdir/asdf

これは安全性のチェックなどを行わないことに注意してください。タスクの複雑さによっては、これで十分な場合があります。

2
MatthewRock

私は通常、次の1行の関数を使用します。

_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_-古いファイルを上書きします
0
user60561