ลิงค์สัญลักษณ์การอัพเดทแบบเป็นกลุ่มซ้ำ


13

ฉันมีเว็บแอพที่มีลิงก์สัญลักษณ์มากมายในไดเรกทอรีย่อยตลอด ฉันต้องการย้ายแอปไปยังโครงสร้างไดเรกทอรีอื่นและฉันต้องอัปเดต symlink ทั้งหมดเพื่อชี้ไปที่เส้นทางใหม่ ตัวอย่างเช่น:

Old Dir: /home/user/public_html/dev
New Dir: /home/user/public_html/qa
Old Symlink: /home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/dev/images
New Symlink:/home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/qa/images

ปัญหาคือมีจำนวนมากกระจายอยู่ทั่วไดเรกทอรีต่างๆ ฉันจะค้นหาซ้ำจากรูทและสร้าง symlink ทั้งหมดที่ชี้ไปยัง/dev/ด้วยซ้ำได้/qa/อย่างไร

คำตอบ:


17

คำสั่ง 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ในการระบุไฟล์ทั้งหมดในqaไดเรกทอรีที่มีการเชื่อมโยงสัญลักษณ์ที่มีเป้าหมายที่อยู่ในที่ไดเรกทอรีและแต่ละคนก็พิมพ์ออกคำสั่งทุบตีที่จะเข้ามาแทนที่การเชื่อมโยงที่มีการเชื่อมโยงไปยังเส้นทางที่เทียบเท่าในdev qa/หลังจากที่คุณเรียกใช้เพียงแค่เรียกใช้สคริปต์ที่สร้างขึ้นด้วย

bash script.sh

คุณอาจต้องการตรวจสอบด้วยตนเองก่อนเพื่อให้แน่ใจว่าทำงานได้

ต่อไปนี้เป็นfindคำสั่งด้านบนเวอร์ชัน verbose สำหรับการอ่านที่ง่ายขึ้น (แม้ว่าฉันจะไม่จำเป็นต้องเขียนด้วยวิธีนี้ในทางปฏิบัติ):

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

สิ่งนี้จะสร้าง script.sh ที่ว่างเปล่า และการรันคำสั่ง find เป็นอย่างนั้น find /home/user/public_html/qa/ -type l -lname '/home/user/public_html/dev/*' จะไม่แสดงผลใด ๆ
ggutenberg

คุณจำเปลี่ยนเส้นทางไปเป็นเส้นทางจริงในระบบไฟล์ของคุณใช่ไหม? จะเกิดอะไรขึ้นถ้าคุณทำงานเพียงfind /home/usr/public_html/qa/ -type l? หากไม่พบลิงก์สิ่งที่แปลกมากก็เกิดขึ้นกับระบบของคุณ
David Z

ใช่ " find /home/user/public_html/qa/ -type l" แสดงผลลิงก์ แต่การเพิ่มพารามิเตอร์ -lname มันจะไม่ส่งออกอะไร
ggutenberg

ที่จริงแล้วในการทดสอบเพิ่มเติมดูเหมือนว่ามันใช้งานได้ ไม่แน่ใจว่าฉันทำอะไรผิดเมื่อวานนี้ แต่ดูเหมือนว่าใช้ได้แล้ว ขอบคุณ
ggutenberg

แปลก ๆ ถ้าคุณเคยคิดออกว่าเกิดอะไรขึ้นใส่ความคิดเห็นไว้ที่นี่ ฉันอยากรู้.
David Z

5

ในกรณีที่บุคคลอื่นพบสิ่งนี้เมื่อค้นหาวิธีแก้ไข: สร้างไฟล์ชื่อ "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"

คุณสามารถ ofc ใช้ตัวเลือก -lname ในการค้นหาถ้าจำเป็น

หมายเหตุ: คุณต้องใช้ 2x \ ในรูปแบบก่อนที่อักขระใด ๆ ที่ต้องการ \ in sed เนื่องจาก echo จะลบออกหนึ่งอัน ตัวอย่างเช่น

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

ลบออกechoจากบรรทัดสุดท้ายหากคำสั่ง ln ถูกต้อง


อาจเป็นการดีที่จะชี้แจงว่าทั้งechoในบรรทัดสุดท้ายของสคริปต์และechoในfind .. | xargs .. linkmod.sh ...คำสั่งนั้นจำเป็นต้องลบทั้งคู่ออก
Kyle Strand

2

ฉันสร้างสคริปต์ทุบตีlink_rename.shสำหรับการเปลี่ยนชื่อลิงก์สัญลักษณ์ซ้ำในไดเรกทอรีที่กำหนด

#! /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. ไดเรกทอรีที่คุณต้องการดำเนินการเปลี่ยนชื่อชุดของ symlink
  2. รูปแบบเก่า นี่link1คือรูปแบบเก่าซึ่งจะถูกแทนที่
  3. รูปแบบใหม่ นี่link2คือรูปแบบใหม่ที่link1จะถูกแทนที่

สคริปต์จะอ่าน symlink ทั้งหมดซ้ำในไดเรกทอรีโดยใช้find "$DIR" -type l และประมวลผลทีละบรรทัด

$line คือ symlink ที่ต้องเปลี่ยนชื่อ

CUR_LINK_PATH เป็นเส้นทางเก่า

NEW_LINK_PATH ได้มาจากการแทนที่สตริงในพา ธ ลิงก์เก่า

symlink เก่าถูกลบและสร้าง symlink ใหม่โดยใช้ ln -s "$NEW_LINK_PATH" "$line"


0

ฉันสิ้นสุดการเขียนสคริปต์ 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";
            }
        }
    }
}
?>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.