파일을 이동하고 심볼릭 링크로 교체


16

누군가 나에게 다음과 같은 명령을 줄 수 있습니까?

  • 파일을 새 디렉토리로 이동
  • 기존 위치에 새 링크를 향한 심볼릭 링크를 남겨 두십시오.

답변:


19

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

1
스크립트와 설명에 대해 Gilles에게 감사드립니다. 나는 그것을 이해하려고 노력할 것이다!
Yo B.

이것은 정답으로 표시해야한다
스리 Sarnobat에게

이 답변을 더욱 멋지게 만들려면 rsync --remove-source-files시간이 오래 걸릴 수있는 디스크에서 큰 파일을 이동하는 사용자에게 더 유익 할 수 있습니다.
Sridhar Sarnobat

파일이 이미 존재하여 mv 명령을 중지 한 경우와 같이 오류가 발생하면 -e를 사용하여 sh를 호출해야한다고 생각합니다.
Alex

2

이것을 .sh 파일에 넣고 실행 가능하게 만드십시오 ( chmod +x filename).

#!/bin/bash

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

사용 예 :

./test.sh asdf otherdir/asdf

안전 점검 등은 수행되지 않습니다. 작업이 얼마나 복잡한 지에 따라이 정도면 충분할 수 있습니다.


Matthew에게 감사합니다. 하나의 파일에 적용하면 완벽하게 작동합니다. 그러나 이것을 다음과 같은 두 디렉토리로 일반화하는 데 도움을 줄 수 있습니까 ./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf? 그만큼* 당신과 함께 작동하지 않는 것 test.sh. 해결 방법이 있습니까? Thx
Yo B.

2
@kadok MatthewRock의 스크립트는 단일 파일에 대해서만 작동하며 대상은 절대 경로이거나 소스가 현재 디렉토리에 있어야합니다.
Gilles 'SO- 악마 그만'

또한 $ 1은 파일이지만 $ 2는 디렉토리이면 작동하지 않습니다.
Sridhar Sarnobat

0

나는 일반적으로이 단선 함수를 사용합니다 :

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 -이전 파일을 덮어 씁니다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.