एक फ़ाइल को स्थानांतरित करें और इसे एक सिमलिंक द्वारा बदलें


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
धन्यवाद गिल्स, स्क्रिप्ट और स्पष्टीकरण के लिए। मैं समझने की कोशिश करूँगा!
यो बी।

इसे सही उत्तर के रूप में चिह्नित किया जाना चाहिए
श्रीधर सरनोबत

इस उत्तर को और अधिक भयानक बनाने के rsync --remove-source-filesलिए, उन उपयोगकर्ताओं के लिए अधिक जानकारीपूर्ण हो सकता है जो एक डिस्क से बड़ी फ़ाइल को स्थानांतरित कर रहे हैं जो कुछ समय ले सकता है।
श्रीधर सरनोबत

मुझे लगता है कि आपको sh -e के साथ कॉल करना चाहिए, इसलिए यह त्रुटियों पर टूटता है, उदाहरण के लिए यदि आप mv कमांड को रोकते हैं क्योंकि एक फाइल पहले से मौजूद है
एलेक्स

2

इसे .sh फ़ाइल में रखें और इसे निष्पादन योग्य बनाएं ( chmod +x filename):

#!/bin/bash

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

उपयोग उदाहरण:

./test.sh asdf otherdir/asdf

ध्यान दें कि यह कोई सुरक्षा जांच नहीं करता है, आदि इस बात पर निर्भर करता है कि आपका कार्य कितना जटिल है, यह पर्याप्त हो सकता है।


धन्यवाद मैथ्यू, यह पूरी तरह से काम करता है जब एक फ़ाइल पर लागू होता है। लेकिन आप मदद कर सकते हैं मुझे इस तरह दो निर्देशिकाओं को यह generalising: ./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf*अपने साथ काम कर रहे हो करने के लिए प्रतीत नहीं होता test.sh। क्या आपको वर्कअराउंड मिला है? Thx
यो बी।

2
@kadok मैथेरॉक की स्क्रिप्ट केवल एक ही फाइल के लिए काम करती है, और लक्ष्य एक पूर्ण पथ होना चाहिए अन्यथा वर्तमान निर्देशिका में स्रोत होना चाहिए।
गाइल्स एसओ- बुराई को रोकें '

इसके अलावा, यह काम नहीं करेगा यदि $ 1 एक फ़ाइल है लेकिन $ 2 एक निर्देशिका है।
श्रीधर सरनोबत

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