재귀 적으로 일괄 업데이트 심볼릭 링크 다른 디렉토리 구조로 이동해야하며 새

하위 디렉토리에 많은 심볼릭 링크가있는 웹 응용 프로그램이 있습니다. 앱을 다른 디렉토리 구조로 이동해야하며 새 경로를 가리 키도록 모든 심볼릭 링크를 업데이트해야합니다. 예를 들면 다음과 같습니다.

Old Dir : /home/user/public_html/dev
새로운 Dir : /home/user/public_html/qa
Old Symlink : /home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/dev/images
새로운 Symlink :/home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/qa/images

문제는 다양한 디렉토리에 많은 것들이 흩어져 있다는 것입니다. 루트에서 재귀 적으로 검색하고로 가리키는 모든 심볼릭 링크를 다시 만들려면 어떻게 /dev/해야 /qa/합니까?



답변

이 bash 명령은 당신을 위해해야합니다 :

find /home/user/public_html/qa/ -type l -lname '/home/user/public_html/dev/*' -printf 'ln -nsf "$(readlink "%p" | sed s/dev/qa/)" "$(echo "%p" | sed s/dev/qa/)"\n' > script.sh

디렉토리에있는 대상과의 심볼릭 링크 인 디렉토리의 find모든 파일을 식별하는 데 사용 되며 각 파일에 대해 링크를 해당 경로의 링크로 대체하는 bash 명령을 인쇄합니다 . 이것을 실행 한 후 생성 된 스크립트를qadevqa/

bash script.sh

먼저 수동으로 검사하여 작동하는지 확인할 수 있습니다.

다음은 find읽기 쉽 도록 위 명령 의보다 자세한 버전입니다 (실제로이 방법으로 쓸 필요는 없지만).

SRC_DIR="/home/user/public_html/qa"
OLD_TARGET="/home/user/public_html/dev"
SUB="s/dev/qa/"

find $SRC_DIR -type l \
  -lname "$OLD_TARGET/*" -printf \
  'ln -nsf "$(readlink "%p"|sed $SUB)" "$(echo "%p"|sed $SUB)"\n'\
 > script.sh

답변

솔루션을 검색 할 때 다른 사람이이를 발견 한 경우 : 다음을 포함하는 “linkmod.sh”라는 파일을 작성하십시오.

#!/bin/sh
PATTERN1=`echo "$2"`
PATTERN2=`echo "$3"`
LINKNAME=`echo "$1"`
OLDTARGET=`readlink "$1"`
NEWTARGET=`echo "$OLDTARGET" \
| sed -e 's/'"$PATTERN1"'/'"$PATTERN2"'/'`
echo ln -nsf "$NEWTARGET" "$LINKNAME"

실행

find . -type l -print0 | xargs -0IX echo linkmod.sh X "pattern1" "pattern2"

필요한 경우 찾기에서 -lname 옵션을 사용할 수 있습니다.

참고 : echo는 하나를 제거하므로 sed에서 \를 필요로하는 문자보다 먼저 패턴에 2x \를 사용해야합니다. 예를 들어

find . -type l -print0 | xargs -0IX echo linkmod.sh X "folder\\ name\\/file" "folder2\\ name\\/file"

echoln 명령이 올바른 경우 마지막 행에서를 제거 하십시오.


답변

link_rename.sh주어진 디렉토리에서 재귀 적으로 이름을 바꾸는 심볼릭 링크에 대한 bash 스크립트 를 만들었습니다.

#! /bin/bash

DIR=$1
OLD_PATTERN=$2
NEW_PATTERN=$3

while read -r line
do
    echo $line
    CUR_LINK_PATH="$(readlink "$line")"
    NEW_LINK_PATH="$CUR_LINK_PATH"
    NEW_LINK_PATH="${NEW_LINK_PATH/"$OLD_PATTERN"/"$NEW_PATTERN"}"
    rm "$line"
    ln -s "$NEW_LINK_PATH" "$line"
done <<< $(find "$DIR" -type l)

다음과 같이 실행될 수 있습니다 link_rename.sh /home/human/dir link1 link2

이 스크립트에는 3 가지 인수가 있습니다.

  1. 심볼릭 링크의 일괄 이름 바꾸기를 수행하려는 디렉토리
  2. 오래된 패턴. 여기 link1에 교체 될 오래된 패턴이 있습니다.
  3. 새로운 패턴. 교체 할 link2새로운 패턴은 다음과 같습니다.link1

스크립트는 디렉토리의 모든 심볼릭 링크를 사용하여 find "$DIR" -type l
한 줄씩 재귀 적으로 처리하고 처리합니다.

$line 이름을 바꿔야하는 심볼릭 링크입니다

CUR_LINK_PATH 오래된 길이야

NEW_LINK_PATH 이전 링크 경로에서 문자열 대체를 수행하여 얻습니다.

이전 symlink가 제거되고 다음을 사용하여 새 symlink가 작성됩니다. ln -s "$NEW_LINK_PATH" "$line"


답변

트릭을 수행하는 것처럼 보이는 명령 행 PHP 스크립트를 작성했습니다.

<?php
//Run via command-line
$dir = new RecursiveDirectoryIterator('.');
foreach(new RecursiveIteratorIterator($dir) as $file) {
    //$link = readlink($file);
    if(is_link($file)) {
        $old_link = readlink($file);
        $new_link = str_ireplace("/joomla/", "/qa/", $old_link);
        if($new_link != $old_link) {
            exec('rm "'.$file.'"');
            exec('ln -fs "'.$new_link.'" "'.$file.'"');
            $new_link = readlink($file);
            if($new_link == $old_link) {
                echo $file."\t".$old_link."\t".$new_link."\n";
            }
        }
    }
}
?>