फ़ाइलों के साथ प्रतीकात्मक लिंक बदलें


27

क्या वे जिस फ़ाइल को लिंक करते हैं, उसके साथ सभी प्रतीकात्मक लिंक को बदलने का एक आसान तरीका है?


3
आप कौनसी समस्याएं हल करने की कोशिश कर रहे हैं?
Daniel Beck

3
मेरे पास एक और ड्राइव पर प्रतीकात्मक लिंक का एक गुच्छा है। मुझे उस ड्राइव से सभी फ़ाइलों को स्थानांतरित करने की आवश्यकता है जो कहीं और संदर्भित हैं ताकि मैं इसे हटा सकूं।
Marty Trenouth

जवाबों:


12

"आसान" की कुछ परिभाषाओं के लिए:

#!/bin/sh
set -e
for link; do
    test -h "$link" || continue

    dir=$(dirname "$link")
    reltarget=$(readlink "$link")
    case $reltarget in
        /*) abstarget=$reltarget;;
        *)  abstarget=$dir/$reltarget;;
    esac

    rm -fv "$link"
    cp -afv "$abstarget" "$link" || {
        # on failure, restore the symlink
        rm -rfv "$link"
        ln -sfv "$reltarget" "$link"
    }
done

इस स्क्रिप्ट को तर्कों के रूप में लिंक नामों के साथ चलाएं, उदा। के माध्यम से find . -type l -exec /path/tos/script {} +


2
संपादन, एनॉन, लेकिन स्क्रिप्ट के लिए धन्यवाद कर देता है सभी आवश्यक स्थानों में चर को उद्धृत करके, रिक्त स्थान के साथ फ़ाइल नाम को संभालें। बदलना "$var" सेवा मेरे "${var}" श / बश में एक noop है। मैंने एक बैशवाद को हटा दिया ( [[ ), बाकी पॉसिक्स श के साथ संगत है।
grawity

सिम्कलिन विफलताओं से निपटने के लिए एक और भी मजबूत तरीका है cp उसी निर्देशिका में एक अस्थायी फ़ाइल के लिए mv -f मूल में वह अस्थायी फ़ाइल। इससे लोगों को परेशानियों से बचना चाहिए Ctrl-C या फाइलसिस्टम भरने के बीच rm तथा cp आदेशों (इस प्रकार नए को भी रोकना ln काम करने से)। अस्थायी फ़ाइल नाम के साथ स्पॉट करना आसान है ls -a यदि आवश्यक हो तो बाद में सफाई के लिए।
Mr Fooz

एक साइड नोट के रूप में, मैं गंभीरता से याद नहीं कर सकता कि मैंने सिर्फ उपयोग क्यों नहीं किया abstarget=$(readlink -f "$link") के स्थान पर मामला ब्लॉक करें, लेकिन यह पोर्टेबिलिटी का कारण हो सकता है।
grawity

17

एक नई निर्देशिका के लिए डेटा को कॉपी करने के लिए बस टार का उपयोग करना आसान हो सकता है।

-H      (c and r mode only) Symbolic links named on the command line will
        be followed; the target of the link will be archived, not the
        link itself.

आप कुछ इस तरह का उपयोग कर सकते हैं

tar -hcf - sourcedir | tar -xf - -C newdir

tar --help:
-H, --format=FORMAT        create archive of the given format
-h, --dereference          follow symlinks; archive and dump the files they point to

1
मुझे आपके समाधान से प्यार है, लेकिन मैं आपके संदेश के अंतिम भाग को नहीं समझता। मेरे लिए आपको करना चाहिए: tar -hcf - sourcedir | tar -xf - -C newdir
Seb DA ROCHA

1
सहमत, इस जवाब को टिप्पणी के अनुसार अद्यतन करने की आवश्यकता होगी।
astabada

1
cp -L सरल उपाय है
plesiv

@ त्सिव सच, और पॉज़िक्स-आज्ञाकारी, लेकिन सभी नहीं cp कार्यान्वयन निर्देशिकाओं की प्रतिलिपि बनाएंगे।
Wyatt8740

12

अगर मैं तुम्हें सही ढंग से समझ गया -L का झंडा cp कमांड को वही करना चाहिए जो आप चाहते हैं।

बस सभी सिम्लिंक को कॉपी करें और यह उन्हें उन फाइलों से बदल देगा जो वे इंगित करते हैं।


3
धन्यवाद - लगभग मुझे क्या चाहिए: मुझे कुछ ऐसा करना था: cp -L files tmp/ && rm files && cp tmp/files . यदि आप स्पष्ट करते हैं, तो आप शायद अधिक लोगों की मदद करेंगे ...
sage

5

"आसान" आप का एक कार्य होगा, सबसे अधिक संभावना है।

मैं शायद एक स्क्रिप्ट लिखूंगा जो प्रतीकात्मक रूप से लिंक की गई फ़ाइलों को खोजने के लिए "खोज" कमांड लाइन उपयोगिता का उपयोग करता है, फिर फ़ाइल को हटाने और बदलने के लिए आरएम और सीपीपी कॉल करता है। आप शायद यह भी अच्छी तरह से कर सकते हैं कि एक्शन चेक द्वारा कॉल की गई कार्रवाई है जो कि पर्याप्त लिंक है जो कि सिम्पल लिंक को भी स्थानांतरित करने से पहले छोड़ दिया गया है।

एक अन्य समाधान यह हो सकता है कि फ़ाइल सिस्टम को किसी ऐसी चीज़ के माध्यम से माउंट किया जाए जो सिम्बियन लिंक (जैसे सांबा) को छुपाती है, फिर बस उसी में से सब कुछ कॉपी करें। लेकिन कई मामलों में, ऐसा कुछ अन्य समस्याओं को पेश करेगा।

आपके प्रश्न का अधिक प्रत्यक्ष उत्तर संभवतः "हां" है।

संपादित करें: अधिक विशिष्ट जानकारी के लिए अनुरोध के अनुसार। के अनुसार खोजने के लिए आदमी पृष्ठ , यह कमांड 2 निर्देशिकाओं की गहराई से सभी सिम्बल लिंक फाइलों को /: से सूचीबद्ध करेगा।

find / -maxdepth 2 -type l -print

( यह यहाँ पाया गया था )

खोजने पर कुछ निष्पादित करने के लिए:

find / -maxdepth 2 -type l -exec ./ReplaceSymLink.sh {} \;

मुझे विश्वास है कि मैं अभी बनी कुछ स्क्रिप्ट को कॉल करूंगा, और आपको जो फ़ाइल नाम मिला है, उसमें पास हो जाऊंगा। वैकल्पिक रूप से, आप फ़ाइल के लिए खोज आउटपुट को कैप्चर कर सकते हैं (तब "blah] & gt; symlinks.data", आदि का उपयोग करें) फिर उस फ़ाइल को उस स्क्रिप्ट में पास करें जिसे आपने मूल रूप से कॉपी करने के लिए लिखा है।


? थोड़ा सामान्य - क्या आप विस्तृत कर सकते हैं?
Linker3000

2
वाक्य रचना है -exec ./ReplaceSymLink.sh {} \;
grawity

यह आइटमों को खोजने के लिए जाता है और लिंक के स्थान पर उत्तर का उपयोग किया जाता है!
Marty Trenouth

2
find . -type l -exec cp --dereference --recursive '{}' '{}'.dereferenced \;

प्रत्येक सिम्लिंक की गई फ़ाइल / फ़ोल्डर की एक प्रति बनाएगा <filename>.dereferenced, जो सुरक्षित है (यदि कम सुविधाजनक है) सीधे उन्हें बदलने के बजाय। सिमिलिंक के फ़ाइलनाम में कॉपी किए गए डेटा को स्थानांतरित करना पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है।


2

पिछले विचारों में से कुछ का उपयोग करते हुए, निम्नलिखित कमांड मूल की एक प्रति के साथ हर सिम्कलिन को पुन: बदल देगा:

find . -type l -exec bash -c "echo 'Replacing {} ...';  cp -LR '{}' '{}'.dereferenced;  rm '{}';  mv '{}'.dereferenced '{}'" \;

2

यह मेरे द्वारा उपयोग किया गया oneliner है: मान लें कि सभी स्थानीय फाइलें "स्रोत" में किसी अन्य फ़ाइल के लिंक हैं। आप पैटर्न या "खोज" के साथ फ़ाइल चयन को परिष्कृत कर सकते हैं। कृपया, उपयोग करने से पहले समझें।

एफ में * के लिए; cp --remove-गंतव्य स्रोत / $ f $ f; किया हुआ

उम्मीद है की यह मदद करेगा


कैसे का उपयोग करने के बारे में पठन: एफ में * के लिए; do cp ---- हटाओ-गंतव्य "$ (readlink $ f)" "$ f"; किया हुआ
Diego

हां, यह एक अच्छा विचार है, लेकिन आप ऑपरेशन पर कुछ नियंत्रण खो देते हैं। मेरे समाधान की एक सीमा यह है कि यह बीच में खाली या बहुत लंबी सूचियों वाली फ़ाइलों के लिए काम नहीं करता है। संभवत: अंतिम समाधान 'निकालें - गंतव्य' के साथ ऊपर 'खोज --exec' को एक साथ रखना है। कोई भी कोशिश करना चाहता है?
MastroGeppetto

बीच के रिक्त स्थान को डबल्यूकोट में "$ f" लगाकर कम किया जाना चाहिए। यहां बताया गया है कि मैं इसे "लूप के लिए" के बजाय "फाइंड & amp; xargs" के साथ कैसे उपयोग करता हूं: खोज। {} ")" {} "" मैंने इसे दृश्यता के लिए एक अलग उत्तर के रूप में पोस्ट किया है। superuser.com/a/1329543/499386
Diego

1

लूत के अच्छे जवाब हैं, लेकिन जब से आप कुछ आसान ढूंढ रहे थे

for i in *; do link=$(readlink $i) && rm $i && mv $link $i; done

थोड़ी वृद्धि प्रतीकात्मक लिंक खोजने में मदद करेगी: `खोजें में lnk के लिए। -प्रकार l`; do src = $ (readlink $ lnk) & amp; & amp; rm $ lnk & amp; & amp; mv $ src $ lnk; किया (हालांकि पदानुक्रम के साथ परीक्षण नहीं किया गया है, बैकटिक्स के साथ सावधान रहें)
Roman Susi

1

जब आप सामान्य रूप से लिंक का पालन करने और फ़ाइल की प्रतिलिपि बनाने की अपेक्षा करेंगे तो मुझे gwenview प्रतिलिपि लिंक के साथ भी यही समस्या थी।

मैंने सभी लिंक्स का पालन करके और डायरेक्‍ट्री की सभी प्‍वाइंट-टू-फाइल्‍स को कॉपी करके डायरेक्‍ट्री को 'क्‍लीन' करने के लिए जो किया था, वह एक स्‍क्रैच डायरेक्टरी बना रहा था, उदा।

"for file in `ls`; do cp -L $file scratchdir/$file; done; mv scratchdir/* ./" 

यह एक स्क्रिप्ट में डालने के लिए बहुत खतरनाक है क्योंकि कोई जाँच नहीं है लेकिन इसने मेरी समस्या को ठीक कर दिया है।




0

मैंने एक-लाइन संस्करण किया, क्योंकि मेरे वेब-होटल ने बैश-स्क्रिप्ट की अनुमति नहीं दी थी और इसने मेरे लिए ठीक काम किया:

before:
> find . -type l | wc -l
358

> for link in `find . -type l` ; do echo "$link : "; ls -al $link ; cp $link notalink; unlink $link; mv notalink $link ; ls -al $link; done
...

after:
> find . -type l | wc -l
0
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.