मेरे पास "मैं सूजी और शादी से प्यार करता हूं" और मैं "सूजी" को "सारा" में बदलना चाहता हूं।
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
परिणाम इस तरह होना चाहिए:
firstString="I love Sara and Marry"
मेरे पास "मैं सूजी और शादी से प्यार करता हूं" और मैं "सूजी" को "सारा" में बदलना चाहता हूं।
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
परिणाम इस तरह होना चाहिए:
firstString="I love Sara and Marry"
जवाबों:
किसी दिए गए स्ट्रिंग के साथ एक पैटर्न की पहली घटना को बदलने के लिए , उपयोग करें :${parameter/pattern/string}
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"
# prints 'I love Sara and Marry'
सभी घटनाओं को बदलने के लिए , उपयोग करें :${parameter//pattern/string}
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(यह में प्रलेखित है बैश संदर्भ मैनुअल , §3.5.3 "शैल पैरामीटर विस्तार" ।)
ध्यान दें कि यह सुविधा POSIX द्वारा निर्दिष्ट नहीं है - यह एक बैश एक्सटेंशन है - इसलिए सभी यूनिक्स गोले इसे लागू नहीं करते हैं। प्रासंगिक POSIX प्रलेखन के लिए, ओपन ग्रुप टेक्निकल स्टैंडर्ड बेस स्पेसिफिकेशन्स, अंक 7 , शेल एंड यूटिलिटीज वॉल्यूम, Par2.6.2 "पैरामीटर एक्सपेंशन" देखें ।
\n
उस संदर्भ में एक नई पंक्ति नहीं बल्कि खुद का प्रतिनिधित्व करेंगे। मैं परीक्षण करने के लिए अब बैश काम सही नहीं है, लेकिन आप की तरह कुछ लिखने के लिए सक्षम होना चाहिए, $STRING="${STRING/$'\n'/<br />}"
। (हालांकि आप शायद चाहते हैं STRING//
- प्रतिस्थापित-सभी - बस के बजाय STRING/
।)
echo ${my string foo/foo/bar}
। आपको आवश्यकता होगीinput="my string foo"; echo ${input/foo/bar}
//
सीधे उल्लेख करने के बजाय , यह उल्लेख करता है कि क्या होता है "यदि पैटर्न ' /
' 'से शुरू होता है " (जो कि सटीक भी नहीं है, क्योंकि शेष वाक्य मानता है कि अतिरिक्त /
वास्तव में हिस्सा नहीं है पैटर्न) - लेकिन मुझे किसी भी बेहतर स्रोत का पता नहीं है।
यह पूरी तरह से बैश स्ट्रिंग हेरफेर के साथ किया जा सकता है:
first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}
यह केवल पहली घटना की जगह लेगा; उन सभी को बदलने के लिए, पहले स्लैश को दोगुना करें:
first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"
डैश के लिए पिछले सभी पोस्ट काम नहीं कर रहे हैं
POSIX sh
संगत समाधान है:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
echo
तर्क के आसपास लापता उद्धरण भी जोड़े । यह भ्रामक रूप से सरल तारों के साथ उद्धृत किए बिना काम करता है, लेकिन आसानी से किसी भी nontrivial इनपुट स्ट्रिंग (अनियमित रिक्ति, शेल मेटाचैकर, आदि) पर टूट जाता है।
इसे इस्तेमाल करे:
sed "s/Suzi/$secondString/g" <<<"$firstString"
sed
यदि स्ट्रिंग्स में RegExp वर्ण हैं , तो इसका उपयोग करना बेहतर है ।
echo ${first_string/Suzi/$second_string}
यह विंडोज के लिए पोर्टेबल है और कम से कम पुराने के साथ काम करता है जैसे कि बैश 3.1।
यह दिखाने के लिए कि आपको इसे टालने की ज़रूरत नहीं है, यह दिखाने के लिए:
/home/name/foo/bar
इस मामले में:
~/foo/bar
लेकिन केवल अगर /home/name
शुरुआत में है। हमें जरूरत नहीं है sed
!
यह देखते हुए कि बैश हमें जादुई चर देता है $PWD
और $HOME
हम कर सकते हैं:
echo "${PWD/#$HOME/\~}"
संपादित करें: उद्धरण / बचने पर नोट के लिए टिप्पणियों में मार्क हैफर्कैम्प के लिए धन्यवाद ~
। "
ध्यान दें कि कैसे चर $HOME
में स्लैश होते हैं लेकिन यह कुछ भी नहीं तोड़ता है।
आगे पढ़ें: उन्नत बैश-पटकथा गाइड ।
यदि उपयोग sed
करना आवश्यक है, तो हर चरित्र से बचना सुनिश्चित करें ।
sed
करने से रोक दिया । बैश स्ट्रिंग प्रतिस्थापन के लिए एक कमांड के आउटपुट का उपयोग करने के लिए जादू चर की तुलना में अधिक सामान्य तरीका प्रदान करता है? आपके कोड के लिए, मुझे बैश को $ HOME में विस्तारित करने से बचने के लिए बचना पड़ा । इसके अलावा, आपकी आज्ञा में क्या है? pwd
$PS1
~
#
~
: ध्यान दें कि मैंने सामान कैसे उद्धृत किया। हमेशा सामान उद्धृत करने के लिए याद रखें! और यह सिर्फ जादुई चर के लिए काम नहीं करता है: कोई भी चर प्रतिस्थापन के लिए सक्षम है, स्ट्रिंग की लंबाई, और अधिक, बैश के भीतर। अपने $PS1
उपवास की कोशिश करने के लिए बधाई : आप भी दिलचस्पी ले $PROMPT_COMMAND
सकते हैं यदि आप किसी अन्य प्रोग्रामिंग भाषा में अधिक सहज हैं और एक संकलित संकेत को कोड करना चाहते हैं।
echo "${PWD/#$HOME/~}"
मेरे को प्रतिस्थापित नहीं करता $HOME
साथ ~
। ~
साथ \~
या '~'
काम से प्रतिस्थापित करना । इनमें से कोई भी बैश 4.2.53 पर एक और डिस्ट्रो पर काम करता है। क्या आप ~
बेहतर संगतता के लिए बोली या भागने के लिए अपनी पोस्ट को अपडेट कर सकते हैं ? मेरे "मैजिक वेरिएबल्स" प्रश्न का क्या मतलब था: क्या मैं बैश के वैरिएबल सबस्टेशन का उपयोग कर सकता हूं, उदाहरण के लिए, uname
इसे पहले वेरिएबल के रूप में सहेजे बिना? मेरे व्यक्तिगत के लिए $PROMPT_COMMAND
, यह जटिल है ।
चूंकि मैं एक टिप्पणी नहीं जोड़ सकता। @ruaka उदाहरण को अधिक पठनीय बनाने के लिए इसे इस तरह लिखें
full_string="I love Suzy and Mary"
search_string="Suzy"
replace_string="Sara"
my_string=${full_string/$search_string/$replace_string}
or
my_string=${full_string/Suzy/Sarah}
शुद्ध POSIX खोल विधि है, जो विपरीत रोमन Kazanovskyi की sed
आधारित जवाब कोई बाहरी उपकरण की जरूरत है, सिर्फ खोल के अपने देशी पैरामीटर विस्तार । ध्यान दें कि लंबे फ़ाइल नाम को छोटा किया जाता है ताकि कोड एक पंक्ति में बेहतर हो सके:
f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"
आउटपुट:
I love Sara and Marry
यह काम किस प्रकार करता है:
सबसे छोटा प्रत्यय पैटर्न निकालें। "${f%$t*}"
" I love
" यदि प्रत्यय $t
" Suzi*
" $f
" " में है। I love
Suzi and Marry
लेकिन अगर t=Zelda
, फिर "${f%$t*}"
कुछ भी नहीं हटाता है, और पूरे स्ट्रिंग को लौटाता है " I love Suzi and Marry
"।
यह परीक्षण करने के लिए इस्तेमाल करता है, तो है $t
है में $f
से [ "${f%$t*}" != "$f" ]
जो करने के लिए मूल्यांकन करेंगे सच है, तो $f
स्ट्रिंग है " Suzi*
" और झूठी नहीं तो।
यदि परीक्षण रिटर्न सच , का उपयोग कर वांछित स्ट्रिंग निर्माण निकालें सबसे छोटा प्रत्यय पैटर्न ${f%$t*}
" I love
" और सबसे छोटा उपसर्ग पैटर्न निकालें ${f#*$t}
" and Marry
", के साथ 2 स्ट्रिंग $s
" Sara
" के बीच में।
मुझे पता है कि यह पुराना है, लेकिन जब से किसी ने awk का उपयोग करने के बारे में उल्लेख नहीं किया है:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
echo [string] | sed "s/[original]/[target]/g"