एक खोल में एक स्ट्रिंग के अंतिम चरित्र को कैसे प्राप्त करें?


125

मैंने स्ट्रिंग के अंतिम वर्ण को प्राप्त करने के लिए निम्नलिखित पंक्तियाँ लिखी हैं:

str=$1
i=$((${#str}-1))
echo ${str:$i:1}

इसके लिए काम करता है abcd/:

$ bash last_ch.sh abcd/
/

यह काम नहीं करता हैabcd* :

$ bash last_ch.sh abcd*
array.sh assign.sh date.sh dict.sh full_path.sh last_ch.sh

यह वर्तमान फ़ोल्डर में फ़ाइलों को सूचीबद्ध करता है

जवाबों:


97

यही कारण है कि आपको अपने चर को उद्धृत करने की आवश्यकता है:

echo "${str:$i:1}"

अन्यथा, बैश चर का विस्तार करता है और इस मामले में मुद्रण से पहले ग्लोबिंग करता है। स्क्रिप्ट को पैरामीटर उद्धृत करना बेहतर है (यदि आपके पास एक मेल फ़ाइल नाम है):

sh lash_ch.sh 'abcde*'

बैश संदर्भ पुस्तिका में विस्तार का क्रम भी देखें । फ़ाइल नाम के विस्तार से पहले चर का विस्तार किया जाता है।

अंतिम वर्ण प्राप्त करने के लिए आपको बस -1सूचकांक के रूप में उपयोग करना चाहिए क्योंकि नकारात्मक सूचकांक स्ट्रिंग के अंत से गिना जाता है:

echo "${str: -1}"

बृहदान्त्र ( :) के बाद का स्थान आवश्यक है।

यह दृष्टिकोण अंतरिक्ष के बिना काम नहीं करेगा।


62
BTW, नकारात्मक सूचक सही से गिनते हैं, इसलिए "${1: -1}"पर्याप्त है।
कोरोबा

7
आपको औपचारिक समाधान के रूप में जवाब देना चाहिए, यहां टिप्पणियों में नहीं।
बीएमडब्ल्यू

FYI करें: आप इसे "वन-लाइनर" के रूप में भी कर सकते हैं echo "${str:$((${#str}-1)):1}"। यह आपको पीछे चल रहे पात्रों को अलग-अलग करने की अनुमति देता है। मेरे लिए यह काम bash v4.1.0 (1)
SaxDaddy

16
@ चोरोबा का जवाब: धिक्कार है अंतरिक्ष पर! यह हमेशा मुझे ऊपर ले जाता है: "${1:-1}काम नहीं करता है "!
mxmlnkn

192

प्रति @ वेरिएबल, वैरिएबल को उद्धृत करना महत्वपूर्ण है, लेकिन क्योंकि मैंने इस पोस्ट को 5 बार पढ़ा है ताकि टिप्पणियों में हाथ में प्रश्न के लिए एक सरल दृष्टिकोण मिल सके ...

str='abcd/'
echo "${str: -1}"

आउटपुट: /

str='abcd*'
echo "${str: -1}"

आउटपुट: *

इसमें उपरोक्त में भाग लेने वाले सभी को धन्यवाद; मैंने उचित रूप से धागे में + 1 जोड़ा है!


25
NB: अंतरिक्ष के अंदर ध्यान दें, अंतरिक्ष के ${std: -1}बिना यह काम नहीं करेगा। मैं इसमें भाग गया और पाया कि ${std:~0}यह (अंतरिक्ष के साथ या बिना) भी काम करता है। यह सुनिश्चित नहीं है कि अगर यह दस्तावेजित व्यवहार है, तो मैंने इसे देखने की जहमत नहीं उठाई।
बार्ट

4
यह प्रलेखित है। मैन बैश का कहना है: अंकगणित के साथ शुरू होने वाले भाव - पूर्ववर्ती
व्हाट्सएप

3
यह कमाल है, साझा करने के लिए धन्यवाद। BASH मैनपेज पढ़ने के लिए लगभग भारी है, हालांकि मैं कई बार वहां गया हूं। मुझे लगता है कि वे शेल स्क्रिप्टिंग लोल के आसपास एक कॉलेज का पाठ्यक्रम बना सकते हैं।
क्विकशिफ्टिन

3
यह समाधान .shस्क्रिप्ट में तब काम नहीं करता है जब किसी वर्ण को पुनर्प्राप्त करने के लिए एक चर को निर्दिष्ट करने की कोशिश की जाती है। उदाहरण के लिए, declare LAST=$(echo "${str: -1}") यह एक बुरा सिंटैक्स त्रुटि दिखाती हुई लाल पट्टी में परिणत होगी:
krb686

3
अगर संपादक वाक्यविन्यास जाँच पसंद नहीं है कि अंतरिक्ष की कोशिश${str:0-1}
ttt

36

मुझे पता है कि यह एक बहुत पुराना धागा है, लेकिन किसी ने भी इस बात का उल्लेख नहीं किया कि यह सबसे साफ जवाब है:

echo -n $str | tail -c 1

ध्यान दें कि -nसिर्फ इतना है कि गूंज अंत में एक नई रेखा शामिल नहीं करता है।


15
$ {Str: -1} से अधिक साफ होने के करीब भी नहीं है
shrewmouse

8
यह क्लीनर है क्योंकि यह बैश-इस्म पर भरोसा नहीं करता है, इसलिए यह किसी भी पॉज़िक्स शेल के साथ काम करेगा।
जॉन ईकेनबेरी

सबसे "बैशिस्ट" क्या है? "$ {str: -1}" और ... सबसे क्लीनर क्या है? "$ {str: -1}" बैश है बैश्ट! :-)
रोजर

किसी बड़ी फ़ाइल पर अंतिम वर्णों को मुद्रित करने का प्रयास करने वाले के लिए, इसने मेरे लिए काम किया: बिल्ली उपयोगकर्ता / फ़ोल्डर / file.json | टेल -c 1 आप उन अक्षरों की संख्या को बदल सकते हैं, जिन्हें आप प्रिंट करना चाहते हैं।
डिएगो सेरानो

5

awk script का उपयोग कर एक और समाधान:

पिछले 1 चार्ट:

echo $str | awk '{print substr($0,length,1)}'

पिछले 5 वर्ण:

echo $str | awk '{print substr($0,length-5,5)}'

1
ऐसा नहीं है कि ओपी ने क्या मांगा, लेकिन यह सबसे अच्छा समाधान है जिसे मैंने एक फ़ाइल के साथ उपयोग करने के लिए पाया है। अधिकांश अन्य दृष्टिकोण इसे करने के लिए एक फ़ाइल के रूप में काम नहीं करेंगे: cat file | awk '{print substr($0,length,1)}'धन्यवाद!
xmar

4

इकलौती रेखा:

${str:${#str}-1:1}

अभी:

echo "${str:${#str}-1:1}"

1
आप दो जोड़े कोष्ठक का उपयोग क्यों करते हैं? इसके अलावा, 4.2 के बाद से, तो आप नकारात्मक ऑफसेट, के रूप में quickshiftin के जवाब में दिखाया गया है का उपयोग कर सकते हैं: echo "${str: -1}"पर्याप्त (के बीच की जगह कोई आपत्ति है :और -)।
गनीउरफ_गनीउरफ

कोष्ठक संचालन के लिए दो जोड़ी कोष्ठक का उपयोग किया जाता है
एडुआर्डो क्युमो

नहीं। कृपया मैनुअल के उस प्रासंगिक हिस्से को देखें जहाँ आप पढ़ेंगे: लंबाई और ऑफसेट अंकगणितीय अभिव्यक्तियाँ हैं ( शैल अंकगणित देखें ); इसलिए आप पहले से ही शेल अंकगणित में हैं और आपको किसी भी कोष्ठक की आवश्यकता नहीं है। इसके अलावा, अगर आपने जो कहा वह सच था, तो इसके साथ अंकगणित का विस्तार होना अधिक तर्कसंगत होगा $((...))
गनीउर_गनीउरफ़

@gniourf_gniourf आप सही हैं! मैं अब आपके पिछले प्रश्न को समझता हूं। उत्तर अद्यतन
एडुआर्डो क्युमो

4

अब तक के प्रत्येक उत्तर का अर्थ है "खोल" शब्द का अर्थ बाश के समान है।

यह एक मानक बॉर्न शेल में ऐसा कैसे कर सकता है:

printf $str | tail -c 1

1
echo -nuser5394399 द्वारा प्रस्तावित के रूप में समस्याओं से बचा जाता है जब $strविशेष प्रारूप वर्ण होते हैं।
कॉनरेड मेयर

-nस्विच एक bashism है। यह डैश, आदि के रूप में मानक बॉर्न शेल में काम नहीं करेगा ... जो मेरे उत्तर का बिंदु था।
ppp

1
काफी बशीवाद नहीं है, लेकिन POSIX यह मानता है कि यह कार्यान्वयन परिभाषित है ("यदि पहला ऑपरेंड एक -n है, या यदि किसी भी ऑपरेंड में <backslash> वर्ण है, तो परिणाम कार्यान्वयन-परिभाषित हैं")। इसके बजाय आपका जवाब printf "%s" "$str" | ...:-) के साथ तय किया जा सकता है ।
कॉनरैड मेयर

4

प्रयत्न:

"${str:$((${#str}-1)):1}"

उदाहरण के लिए:

someone@mypc:~$ str="A random string*"; echo "$str"
A random string*
someone@mypc:~$ echo "${str:$((${#str}-1)):1}"
*
someone@mypc:~$ echo "${str:$((${#str}-2)):1}"
g

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