मैं किसी चरित्र को बैश में रखने के बाद सभी पाठ कैसे निकाल सकता हूं?


147

मैं एक चरित्र के बाद सभी पाठ को कैसे हटा सकता हूं, इस मामले में एक बृहदान्त्र (":"), बैश में? क्या मैं कोलन को भी हटा सकता हूं? मुझे नहीं पता कि कैसे।

जवाबों:


134

एक उदाहरण उपयोगी हो सकता है, लेकिन अगर मैंने आपको सही ढंग से समझा, तो यह काम करेगा:

echo "Hello: world" | cut -f1 -d":"

यह "हैलो: वर्ल्ड" को "हैलो" में बदल देगा।


5
cutकाम करता है, लेकिन मैं डेनिस का जवाब बेहतर और अधिक लचीला है। किसी को पता है कि अगर यह एक नई प्रक्रिया की तरह है cut?
JoBu1324

3
बैश के अंतर्निहित पैरामीटर विस्तार सुविधाओं का उपयोग करना बेहतर है , जैसे उप-चल रहे उपकरण बनाने से basenameऔर cut, डेनिस का जवाब नीचे देखें
लुई मैडॉक्स

1
cutस्टडिन से पढ़ सकते हैं, इसलिए यह विशेष रूप से बेहतर है जब आपके पास एक बहुत लंबी स्ट्रिंग है जिसे आपको फ़ाइल की सामग्री की तरह संसाधित करने की आवश्यकता है।
सहस

1
और यह कैसे लागू किया जाएगा hello: world। यह आधा उत्तर है।
के - एसओ में विषाक्तता बढ़ रही है।

यह सबस्ट्रेशन सिंटैक्स का उपयोग करके भी किया जा सकता है जैसे {var /: / ''}, लेकिन केवल बैश में काम करता है ..
महेश

264

बैश (और ksh, zsh, डैश, आदि) में, आप पैरामीटर विस्तार का उपयोग कर सकते हैं %जिसके साथ स्ट्रिंग के अंत से #वर्ण हटाए जाएंगे या जो स्ट्रिंग की शुरुआत से वर्ण हटा देंगे। यदि आप उन वर्णों में से एक का उपयोग करते हैं, तो सबसे छोटा मिलान स्ट्रिंग हटा दिया जाएगा। यदि आप चरित्र को दोगुना करते हैं, तो सबसे लंबे समय तक हटा दिया जाएगा।

$ a='hello:world'
$ b=${a%:*}
$ echo "$b"
hello
$ a='hello:world:of:tomorrow'
$ echo "${a%:*}"
hello:world:of
$ echo "${a%%:*}"
hello
$ echo "${a#*:}"
world:of:tomorrow
$ echo "${a##*:}"
tomorrow

6
यह देशी शेल स्ट्रिंग हेरफेर है, इसलिए कोई अतिरिक्त प्रक्रिया नहीं होगी। संदर्भ बैश पैरामीटर प्रतिस्थापन , बैश स्ट्रिंग हेरफेर और बेहतर बैश स्क्रिप्टिंग
Dodzi Dzakuma

@denniswilliamson मैं एक विशिष्ट स्ट्रिंग की तरह 2 अक्षरों को कैसे हटा सकता था जैसे कि उपयोग करने hello:worldसे बन जाएगा ? hello:wo${a%:*}
3kstc

महान जवाब, बहुत बहुत धन्यवाद, लेकिन यह "${a##*:}"केवल tomorrow= पाने के लिए भी जोड़ना अच्छा होगा )
avtomaton

1
@openCivilisation: आपको संभवतः नियमित अभिव्यक्ति का मिलान करने की आवश्यकता है a='hello:world:of:tomorrow'; pattern=''^([^:]*:).*$'; [[$ a = ~ $ पैटर्न]]; गूंज "$ {BASH_REMATCH [1]}" `। यह तभी मेल खाता है जब कोई कॉलन हो। यदि आप चाहते हैं कि वैकल्पिक होने के लिए, एक अलग पैटर्न का उपयोग करना होगा। बैश रेगेक्स (और सामान्य रूप से रेग्जेस) का स्पष्टीकरण इन टिप्पणियों के दायरे से परे है। आप अन्य प्रश्न पा सकते हैं जो इस पर चर्चा करते हैं या अपना स्वयं का पोस्ट करते हैं।
अगली सूचना तक रोक दिया गया।

1
@ kp123: यह मेरे जवाब में पहला उदाहरण है। दूसरी बार जब मैं इसे दिखाता हूं (जहां "कल" ​​हटा दिया जाता है), तो लगभग वही स्थिति है जिसके बारे में आप पूछ रहे हैं।
अगली सूचना तक रोक दिया गया।


4
egrep -o '^[^:]*:'

क्या आप इसकी व्याख्या कैसे कर सकते हैं, धन्यवाद।
r --dʒɑ

1
egrepसाथ ग्रेप है -E। यह यहाँ नियमित से कोई फर्क नहीं पड़ता grep-ogrep को निर्देश देता है कि वह अभिव्यक्ति से मेल खाने वाली रेखा के केवल एक भाग को प्रिंट करे। ^एक लाइन की शुरुआत के लिए मैच लंगर डाले। [^:]*शून्य या अधिक वर्णों से मेल खाता है जो :वर्ण नहीं हैं । :चरित्र से मेल खाता है :
cdhowie

स्पष्टीकरण के लिए फिर से धन्यवाद
rɑːdʒɑ

3

मान लीजिए कि आपके पास इस प्रारूप में फ़ाइल के साथ एक पथ है:

/dirA/dirB/dirC/filename.file

अब आप केवल वह रास्ता चाहते हैं जिसमें चार "/" शामिल हों। प्रकार

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-4 -d"/"

और आपका आउटपुट होगा

/dirA/dirB/dirC

कट का उपयोग करने का लाभ यह है कि आप बड़े निर्देशिका के साथ-साथ फ़ाइल (इस उदाहरण में) को भी काट सकते हैं, इसलिए यदि आप टाइप करते हैं

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-3 -d"/"

आपका आउटपुट होगा

/dirA/dirB

यद्यपि आप इसे स्ट्रिंग के दूसरी तरफ से भी कर सकते हैं, लेकिन यह टाइपिंग के रूप में इस मामले में बहुत मायने नहीं रखेगा

$ echo "/dirA/dirB/dirC/filename.file" | cut -f2-4 -d"/"

का परिणाम

dirA/dirB/dirC

कुछ अन्य मामलों में अंतिम मामला भी मददगार हो सकता है। मन कि अंतिम आउटपुट की शुरुआत में कोई "/" नहीं है।


2
क्या होगा यदि आपके पास एक निर्देशिका "/resource/views/admin/users/relationships/posts.blade.php" है और आप "/" की अंतिम घटना के बाद सब कुछ काट देना चाहते हैं, यह देखते हुए कि आप कितने "/" नहीं जानते हैं "वर्ण स्ट्रिंग में हैं। इसलिए यहां मैं चाहता हूं कि आउटपुट "/ संसाधन / विचार / व्यवस्थापक / उपयोगकर्ता / रिश्ते /" (या यहां तक ​​कि / संसाधन / विचार / व्यवस्थापक / उपयोगकर्ता / रिश्तेदारों के बिना अनुगामी स्लेश) हो। आप वह कैसे करेंगें?
kp123

-1

":" के अंतिम उदाहरण के बाद सब कुछ ट्रिम करें

cat fileListingPathsAndFiles.txt | grep -o '^.*:'

और यदि आप उस अंतिम को गिराना चाहते हैं ":"

cat file.txt | grep -o '^.*:' | sed 's/:$//'

@ kp123: आप बदलना चाहते चाहते हैं :के साथ /(जहां sed पेट होना चाहिए \/)

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