मैं निर्देशिका और सापेक्ष राशियों को खोजने के लिए $ 0 चर को कैसे विभाजित करूं?


10

$ 0 चर में स्क्रिप्ट की पथ जानकारी है।

  • मैं पथ जानकारी को निरपेक्ष पथ में कैसे बदल सकता हूं? मेरा मतलब है कि ~,।, .. या इसी तरह की प्रक्रिया कैसे करें?
  • मैं पथ जानकारी को निर्देशिका और फ़ाइल नाम में कैसे विभाजित कर सकता हूं?

मैं इसके लिए अजगर / पर्ल का उपयोग कर सकता था, लेकिन यदि संभव हो तो मैं बैश का उपयोग करना चाहता हूं।


आप क्या हासिल करने का प्रयास कर रहे हैं? btw। के साथ एक स्क्रिप्ट बुला ~ / foo.sh मेरी बैश संस्करण (जीएनयू बैश, संस्करण 4.1.5 (2) -release- (x86_64-अज्ञात-linux-gnu)) के साथ $ 0 के लिए मेरे घर निर्देशिका में विस्तार होगा ~
echox

जवाबों:


17

आपको चीजों को संसाधित करने की आवश्यकता नहीं है ~, जैसे शेल आपके लिए करता है। इसीलिए आप ~/filenameकिसी भी स्क्रिप्ट या प्रोग्राम को पास कर सकते हैं और यह काम करता है - वे सभी प्रोग्राम ~खुद को हैंडल नहीं करते हैं, आपका शेल तर्क को रूपांतरित करता है /home/username/filenameऔर इसके बजाय प्रोग्राम को पास करता है:

$ echo ~/filename
/home/mrozekma/filename

यदि आपको एक विहित फ़ाइलनाम की आवश्यकता है (एक जिसमें चीजें शामिल नहीं हैं ..), का उपयोग करें realpath(धन्यवाद नील ):

$ realpath ~/../filename
/home/filename

पथ को निर्देशिका नाम और फ़ाइल नाम में विभाजित करने के लिए उपयोग करें dirnameऔर basename:

$ dirname /foo/bar/baz
/foo/bar

$ basename /foo/bar/baz
baz

मुझे लगता है कि आपका मतलब रियलपैथ है, न कि रीडलिंक। रीडलिंक सामान्य स्थिति में काम नहीं करेगा, अर्थात जब लिंक एक रिश्तेदार पथ का उपयोग करता है और आप लिंक के समान डायर में नहीं हैं।
नील मैय्यूज

@ नील realpathबेहतर है, लेकिन readlinkजब मैं कोशिश करता हूं तो यह काम करने लगता है; क्या आप एक उदाहरण के बारे में जानते हैं जहां यह विफल रहता है?
माइकल Mrozek

1
cd /tmp; touch foo; ln -s foo bar; cd; readlink /tmp/bar। यह रिटर्न fooऔर realpathरिटर्न /tmp/foo, जो आप चाहते हैं।
नील मैय्यूज

1
@ नील, @ मिचेल: readlink -f(नोट -f) लगभग बराबर है realpath, और यह अधिक पोर्टेबल है: readlink -fजीएनयू कोरुटिल्स में और कुछ अन्य प्रणालियों पर भी मौजूद है; realpathअलग से पैक किया जाता है और स्थापित नहीं किया जा सकता है (उदाहरण के लिए केवल 5 नहीं-आम पैकेज उबंटू 10.04 या डेबियन लेन में इस पर निर्भर करते हैं)।
गिलेस का SO-

@ गिल्स: अच्छी बात है। Realpath -f के बारे में अनुस्मारक के लिए धन्यवाद।
नील मैय्यूज

5

माइकल द्वारा बताए गए डारनेम और बेसनेम का उपयोग करना आपके लिए सबसे सुरक्षित तरीका होना चाहिए।

वैसे भी अगर आप वास्तव में "केवल उपकरण को दंश" के साथ ऐसा करना चाहते हैं, तो आप पैरामीटर प्रतिस्थापन का उपयोग कर सकते हैं:

echo `basename $PWD`        # Basename of current working directory.
echo "${PWD##*/}"           # Basename of current working directory.
echo
echo `basename $0`          # Name of script.
echo $0                     # Name of script.
echo "${0##*/}"             # Name of script.
echo
filename=test.data
echo "${filename##*.}"      # data
                            # Extension of filename.

यह उदाहरण सीधे एडवांस्ड बैश स्क्रिप्टिंग गाइड से लिया गया है, जो देखने लायक है।

स्पष्टीकरण बहुत आसान है:

$ {var # पैटर्न} $ var के सबसे छोटे हिस्से को $ var से निकालें जो $ var के फ्रंट एंड से मेल खाता है। $ {var ## पैटर्न} $ var से $ पैटर्न का सबसे लंबा हिस्सा निकालें जो $ var के सामने के छोर से मेल खाता है।

पैटर्न को कुछ रेगेक्स और #या ##कुछ प्रकार के लालची / गैर-लालची संशोधक के रूप में देखें।

यह उपयोगी हो सकता है यदि आपको एक पथ के हिस्से के कुछ अधिक जटिल अर्क करने होंगे।


5
उपयोग करते समय सावधान रहें ${...##...}और इसके बजाय दोस्तों dirnameऔर basenameवे सभी मामलों में काम नहीं करते हैं। उदाहरण के लिए दोनों ${0##*/}और ${0%/*}उसी तरह से विस्तार करें जैसे $0कि $0इसमें कोई नहीं है /
गिल्स एसओ- बुराई को रोकें '

@ गिल्स मैं समझता हूं कि ${0%/*}एक अच्छा विकल्प क्यों नहीं है dirname। हालांकि, ${0##*/}इसके बजाय का उपयोग करने में क्या गलत है basename?
टॉक्सालॉट

@toxalot इस एक के लिए, केवल एक समस्या है जब $0एक अनुगामी के साथ एक निर्देशिका नाम है /। लेकिन मुझे अपनी सलाह पर पछतावा है, क्योंकि dirnameवह कोई बेहतर काम नहीं करती है।
गिल्स एसओ- बुराई को रोकना '

2

realpath एक कमांड है जो आपको वास्तविक रास्ता बताता है (हटाता है .. और प्रतीकात्मक लिंक आदि)

यह FreeBSD के साथ मानक है। इस चर्चा के अनुसार यह लिनक्स के लिए भी उपलब्ध है:

http://www.unix.com/shell-programming-scripting/89294-geting-real-path.html

वह चर्चा भी एक समाधान प्रदान करती है:

$ bash -c "cd /foo/../bar/ ; pwd"

1
वास्तव में, कुछ इस तरह से आमतौर पर काम करता है: MYDIR = "$ (सीडी $ (dirname" $ ​​0 "); pwd)"
केविन कैंटू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.