2012-06-11 17 views
31

का हिस्सा हटाएं मैं स्ट्रिंग में पथ का हिस्सा निकालने का प्रयास कर रहा हूं। मैं पथ:यूनिक्स पथ

/path/to/file/drive/file/path/ 

मैं पहले भाग /path/to/file/drive को हटाने और उत्पादन का उत्पादन करना चाहते हैं:

file/path/ 

नोट: मैं थोड़ी देर के पाश में कई रास्ते है, एक ही /path/to/file/drive के सभी में साथ उन्हें, लेकिन मैं वांछित स्ट्रिंग को हटाने पर 'कैसे करें' की तलाश में हूं।

मैं कुछ उदाहरण पाया, लेकिन मैं उन्हें काम करने के लिए नहीं मिल सकता है:

echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:\2:' 
echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:2' 

\2 स्ट्रिंग के दूसरे भाग जा रहा है और मैं स्पष्ट रूप से कुछ गलत कर रहा हूँ ... शायद वहाँ एक आसान है मार्ग?

उत्तर

28

है आप भी यह करने के लिए POSIX खोल चर विस्तार उपयोग कर सकते हैं।

path=/path/to/file/drive/file/path/ 
echo ${path#/path/to/file/drive/} 

#.. हिस्सा बंद स्ट्रिप्स एक अग्रणी मिलान स्ट्रिंग जब चर का विस्तार किया है; यह विशेष रूप से उपयोगी होता है यदि आपके तार पहले से ही शैल चर में हैं, जैसे कि आप for लूप का उपयोग कर रहे हैं। %... का उपयोग करके, आप चर के अंत से मिलान तारों (उदा।, एक एक्सटेंशन) को भी पट्टी कर सकते हैं। गोर विवरण के लिए bash मैन पेज देखें।

+0

धन्यवाद ... हाँ, मैं इसे करने के लिए खोल चर का उपयोग कर रहा हूँ। दोनों भाग चर हैं, जिन्हें मुझे हटाने की जरूरत है और पूरा पथ है। – esausilva

+0

बढ़िया! लेकिन जब स्ट्रिंग "पाइप से" आ रही है तो मैं इसका उपयोग कैसे कर सकता हूं? – gromit190

+0

@ बिगर अगर स्ट्रिंग एक पाइप से आ रही है तो आपको खोल चर विस्तार का उपयोग करने के लिए इसे एक चर में प्राप्त करने की आवश्यकता है। या बस उस मामले में 'sed' का उपयोग करें। –

9

एक तरह से sed के साथ ऐसा करने

echo /path/to/file/drive/file/path/ | sed 's:^/path/to/file/drive/::' 
+0

धन्यवाद। यह अच्छा काम करता है – esausilva

+0

बहुत बढ़िया - मुझे नहीं पता था कि sed delimiter "/" (स्लैश) के बजाय ":" (कोलन) हो सकता है। सुरुचिपूर्ण और पूरी तरह से काम करता है। – stachyra

+0

आप लगभग किसी भी delimiter का उपयोग कर सकते हैं, न केवल/और: जब तक आप लगातार हों। –

18

आप हिस्सा आप निकाल रहे हैं हार्डकोड करने नहीं करना चाहते हैं: के रूप में बुराई ओटो ने सुझाव दिया

$ s='/path/to/file/drive/file/path/' 
$ echo ${s#$(dirname "$(dirname "$s")")/} 
file/path/ 
+1

मैंने यह देखने के लिए 2 घंटे बिताए। और हार्डकोडिंग के बिना केवल निर्देशिका का नाम प्रदर्शित करने के लिए एक तरीका पोस्ट करने के लिए आप अकेले थे। मुझे ऐसा करने की ज़रूरत है: 'ढूंढें/पथ/से/फ़ाइल/ड्राइव/फ़ाइल/* _ टीएसटी -मैक्सडेप 0-प्रकार डी' लेकिन मैं केवल पूर्ण पथ निर्देशिकाओं के नाम दिखाना चाहता था। और यह किया। – Whitecat

+0

@ व्हाइटकैट वह वही है जो आप चाहते थे, विशेष रूप से "-प्रिंटफ" में "मैन ढूंढें" पढ़ें। आप '-printf "% h \ n"' निर्दिष्ट कर सकते हैं। बस याद रखें कि यह प्रत्येक मिलान फ़ाइल के लिए निर्देशिका मुद्रित करेगा ताकि आप इसे "uniq" के माध्यम से फ़िल्टर करना चाहें। –

3

${path#/path/to/file/drive/} का उपयोग करना निश्चित रूप से ठेठ/सबसे अच्छा यह करने के लिए तरीका है, लेकिन बाद से वहाँ कई एसईडी हैं सुझाव यह इंगित करने लायक है कि अगर आप एक निश्चित स्ट्रिंग के साथ काम कर रहे हैं तो sed overkill है। आप यह भी कर सकते हैं:

echo $PATH | cut -b 21- 

पहले 20 वर्णों को त्यागने के लिए। इसी तरह, आप zsh में ${PATH:20} या bash में $PATH[20,-1] का उपयोग कर सकते हैं।

+0

धन्यवाद। मैं बुराई ओटो के जवाब का उपयोग कर रहा हूँ। जिस भाग को मैं निकालना चाहता हूं वह तय है, लेकिन अगर मैं अपनी स्क्रिप्ट को एक अलग बॉक्स/अलग पथ पर ले जाता हूं तो बदल सकता हूं। इसलिए, जिस हिस्से को मैं एक चर में पथ से हटाना चाहता हूं उसे गिनने से आसान बनाता है .... लेकिन आपके द्वारा प्रदान की गई जानकारी जानना अच्छा है :) – esausilva

2

आप निकालना चाहते हैं पथ के पहले एन भागों, आप निश्चित रूप से glenn's answer में के रूप में basename को एन कॉल, इस्तेमाल कर सकते हैं, लेकिन यह शायद ग्लोबिंग उपयोग करने के लिए आसान है:

path=/path/to/file/drive/file/path/ 
echo "${path#*/*/*/*/*/}" # file/path/ 

विशेष रूप से, ${path#*/*/*/*/*/} का अर्थ है "वापसी $path कम से कम उपसर्ग जिसमें 5 स्लेश" शामिल हैं।

32

यदि आप पथ घटकों की एक निश्चित संख्या को हटाना चाहते हैं, तो आपको -d'/' के साथ उपयोग करना चाहिए।उदाहरण के लिए, यदि path=/home/dude/some/deepish/dir:

पहले दो घटकों निकालने के लिए:

$ echo $path | cut -d'/' -f-3 
/home/dude 

पिछले दो घटकों को निकालने के लिए (rev स्ट्रिंग पराजयों):

# (Add 2 to the number of components to remove to get the value to pass to -f) 
$ echo $path | cut -d'/' -f4- 
some/deepish/dir 

पहले दो घटकों रखने के लिए :

$ echo $path | rev | cut -d'/' -f4- | rev 
/home/dude/some 

अंतिम तीन compon रखने के लिए पिता:

$ echo $path | rev | cut -d'/' -f-3 | rev 
some/deepish/dir 

या, आप एक विशेष घटक से पहले सब कुछ निकालना चाहते हैं, sed काम करेगा:

$ echo $path | sed 's/.*\(some\)/\1/g' 
some/deepish/dir 

या एक विशेष घटक के बाद:

$ echo $path | sed 's/\(dude\).*/\1/g' 
/home/dude 

यह भले ही आसान है

$ echo $path | sed 's/some.*//g' 
/home/dude/ 
: क्या आप निर्दिष्ट कर रहे घटक रखने के लिए नहीं करना चाहते हैं

और अगर आप स्थायी हों आप भी स्लैश से मेल कर सकते हैं:

$ echo $path | sed 's!/some.*!!g' 
/home/dude 

:

$ echo $path | sed 's/\/some.*//g' 
/home/dude 
बेशक

, आप कई स्लैश मिलान कर रहे हैं, आप sed सीमांकक स्विच कर लेना चाहिए ध्यान दें कि ये उदाहरण सभी पूर्ण पथ का उपयोग करते हैं, आपको उन्हें सापेक्ष पथों के साथ काम करने के लिए चारों ओर खेलना होगा।

+0

अद्भुत उत्तर, विशेष रूप से डबल 'रेव' चाल। कल जब मेरी वोट कैप पहनती है तो ऊपर हट जाएगा। –

+1

उत्कृष्ट, मूल यूनिक्स भावना में जानकारीपूर्ण जवाब है, और इतना {chopsquiggleSquiggle} से बेहतर था: केवल: shellversionyoumaynothave। –