बैच अद्यतन प्रतीकात्मक लिंक पुनरावर्ती


13

मेरे पास एक वेब ऐप है जिसमें पूरे उपनिर्देशिकाओं में प्रतीकात्मक लिंक का एक गुच्छा है। मुझे एप्लिकेशन को किसी अन्य निर्देशिका संरचना में ले जाने की आवश्यकता है, और मुझे नए पथ को इंगित करने के लिए सभी सीमलाइन को अपडेट करने की आवश्यकता है। उदाहरण के लिए:

पुराना डिर: /home/user/public_html/dev
नया डिर: /home/user/public_html/qa
पुराना सिमलिंक: /home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/dev/images
न्यू सिमलिंक:/home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/qa/images

समस्या यह है कि विभिन्न निर्देशिकाओं में इनमें से बहुत कुछ बिखरा हुआ है। मैं कैसे रूट से पुन: खोज कर सकता हूं और किसके /dev/साथ इंगित करने वाले सभी सीमलिंक को फिर से बना सकता हूं /qa/?

जवाबों:


17

यह बैश कमांड आपके लिए करना चाहिए:

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, और हर एक के लिए, यह एक bash कमांड प्रिंट करता है जो लिंक को लिंक के साथ समकक्ष पथ में बदल देगा qa/। इसे चलाने के बाद, आप केवल तैयार स्क्रिप्ट को निष्पादित करें

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

यह एक खाली स्क्रिप्ट बनाता है। और खोजने के आदेश के रूप में चल रहा है: find /home/user/public_html/qa/ -type l -lname '/home/user/public_html/dev/*' कुछ भी उत्पादन नहीं करता है।
ggutenberg 4:29 बजे

आपने अपने फ़ाइल सिस्टम पर वास्तविक लोगों के लिए रास्तों को बदलना याद किया, है ना? सिर्फ दौड़ने से क्या होता है find /home/usr/public_html/qa/ -type l? यदि वह लिंक नहीं ढूंढता है, तो आपके सिस्टम के साथ कुछ बहुत ही अजीब चल रहा है।
डेविड जेड

हाँ, " find /home/user/public_html/qa/ -type l" लिंक को आउटपुट करता है। लेकिन -lname पैरामीटर को जोड़ने से यह कुछ भी आउटपुट नहीं करता है।
ggutenberg

दरअसल, आगे के परीक्षण पर ऐसा लग रहा है कि यह काम कर रहा है। मुझे यकीन नहीं है कि मैं कल गलत कर रहा था, लेकिन अब ठीक लगता है। धन्यवाद।
ggutenberg

हुह, अजीब। ठीक है, अगर आप कभी पता लगाते हैं कि क्या गलत हो रहा था, तो यहां एक टिप्पणी डालें। मैं उत्सुक हूँ।
डेविड जेड

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"

यदि आवश्यक हो, तो आप -l नाम विकल्प में toc का उपयोग कर सकते हैं।

ध्यान दें: आपको किसी भी वर्ण से पहले पैटर्न में 2x \ का उपयोग करना होगा जो कि sed में \ _ की आवश्यकता है, क्योंकि गूंज एक को हटा देता है। उदाहरण के लिए

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

echoअंतिम पंक्ति से निकालें यदि ln कमांड सही हैं।


स्पष्ट करने के लिए है कि दोनों अच्छा हो सकता है echoके अंतिम पंक्ति में स्क्रिप्ट और echoमें find .. | xargs .. linkmod.sh ...आदेश अपने आप दोनों की जरूरत है हटा दिया जाना चाहिए।
काइल स्ट्रैंड

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. वह निर्देशिका जिसमें आप सहानुभूति के बैच का नाम बदलना चाहते हैं
  2. पुराना पैटर्न। यहां link1पुराना पैटर्न है जिसे बदला जाएगा
  3. नया पैटर्न। यहां link2नया पैटर्न दिया गया है जिसके साथ link1प्रतिस्थापित किया जाएगा

स्क्रिप्ट पुनरावर्ती रूप से निर्देशिका में सभी सिम्लिंक्स का उपयोग करके पढ़ती है find "$DIR" -type l और इसे लाइन द्वारा लाइन बनाती है।

$line सिमिलिंक है जिसे नाम बदलने की आवश्यकता है

CUR_LINK_PATH पुराना रास्ता है

NEW_LINK_PATH पुराने लिंक पथ में स्ट्रिंग प्रतिस्थापन करके प्राप्त किया जाता है।

पुराने सिमिंक को हटा दिया जाता है और नए सिमिंकल का उपयोग करके बनाया जाता है 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";
            }
        }
    }
}
?>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.