स्ट्रिंग के सामने से वर्णों को 'ड्रॉप' / डिलीट कैसे करें?


13

मेरे पास एक स्ट्रिंग है जिसे मैं हेरफेर करना चाहूंगा। स्ट्रिंग यह है H08W2345678कि मैं इसे कैसे हेरफेर कर पाऊंगा ताकि आउटपुट बस हो W2345678?

इसी तरह अगर मैं अंतिम 4 पात्रों को छोड़ना चाहता था H08W2345678ताकि मुझे मिल H08W234जाए तो मैं यह कैसे करूंगा?


1
तार में हेरफेर करने के कई तरीके हैं। क्या उपयोग करने का कोई विशिष्ट कारण है sed?
don_crissti

@don_crissti कोई कारण नहीं, अनुभव की कमी के अलावा। किसी भी विकल्प का स्वागत है ...
3kstc

@don_crissti, कहानी: एक फ़िल्टर की गई CSV फ़ाइल से, मैं एक लाइन से एक पैरामीटर लेता हूं, जो कि है H08W2345678और इसे हेरफेर करने की आवश्यकता है। W2345678इस मूल्य के साथ अन्य डेटा को भेजे गए ईमेल में डाल दिया जाएगा। क्रोन के साथ थ्योरी ईमेलिंग की जाएगी।
3kstc

@don_crissti awkइसे आईएनजी। मैं एक सरणी बनाता हूं और फिर सरणी के भीतर प्रत्येक तत्व को संशोधित करता हूं (सभी अलग-अलग - यानी सेकंड में एक तिथि आदि में एपोक टाइमस्टिमपिन बदलें)
3kstc

2
आप उस सामान को awk के साथ कर सकते हैं:printf %s\\n "XX,H08W2345678,YY" | awk -F, '{print substr($2, 4); print substr($2, 1, length($2)-4)}'
don_crissti

जवाबों:


19

बस बैश (या ksh93जहां से वाक्य रचना आती है zsh) का उपयोग कर:

string="H08W2345678"

echo "${string:3}"
W2345678

echo "${string:0:-4}"
H08W234

स्ट्रिंग हेरफेर पर अधिक के लिए वूलेज विकी देखें ।


इसके लिए बैश 4.2 या उच्चतर की आवश्यकता होती है। बैश संदर्भ मैनुअल, खंड 3.5.3, '' शेल पैरामीटर विस्तार '' की इस पुरानी प्रति को देखें या पुराने अवरोध को देखने के लिए यहां दिए गए चिक्स का उत्तर (" लंबाई शून्य से अधिक या बराबर संख्या का मूल्यांकन करना चाहिए"); … (Cont'd)
स्कॉट

(जारी) ... देखना (बैश हैकर्स विकी पर) बैश परिवर्तन या (अनुभाग के नीचे के लिए नीचे स्क्रॉल) केस वेस्टर्न रिजर्व विश्वविद्यालय में प्रौद्योगिकी इंफ्रास्ट्रक्चर सेवा संगठन पर बैश समाचार ( "बैश-4.2 को जोड़ा गया" के लिए खोज और फिर संशोधन देखने के लिए "q" पर नीचे स्क्रॉल करें। …………  "${string:0:${#string}-4}" बाश संस्करण में काम करता है 4.1 जब तक लंबाई $stringकम से कम 4 है।
स्कॉट

PS यह भी तार पर चोक होगा abc-e, जैसे , जब आप पहले तीन वर्णों को छोड़ते हैं, तो आपको छोड़ दिया जाता है -e(क्योंकि echo -eआप जो चाहते हैं वह नहीं करता है)।
स्कॉट

8
$ echo "H08W2345678" | sed 's/^.\{3\}//'
W2345678

sed 's/^.\{3\}//'पहले तीन वर्णों को ^.\{3\}ढूंढेगा और रिक्त स्थान से बदल देगा। यहां ^.स्ट्रिंग की शुरुआत में किसी भी चरित्र से मेल खाएगा (स्ट्रिंग ^की शुरुआत इंगित करता है) और \{3\}पिछले पैटर्न से बिल्कुल 3 बार मेल खाएगा। तो, ^.\{3\}पहले तीन पात्रों से मेल खाएगा।

$ echo "H08W2345678" | sed 's/.\{4\}$//'
H08W234

इसी तरह, sed 's/.\{4\}$//'अंतिम चार वर्णों को रिक्त स्थान से बदल देगा ( $स्ट्रिंग के अंत को इंगित करता है)।


1
क्या आप मुझे समझा सकते हैं 's/^.\{3\}//'और 's/.\{4\}$//'जैसा कि मैं अभी भी sed सीख रहा हूँ, बहुत धन्यवाद
3kstc

@ 3kstc: कृपया संपादन की जाँच करें
heemayl

1
केवल कुछ पात्रों के लिए, मैं ...इसके बजाय .\{3\}(मेरे लिए) का उपयोग करना चाहूंगा : इसे पढ़ना आसान है: sed -e 's/^...//' -e 's/....$//' या एकांतर में एक अभिव्यक्ति के साथ sed -r 's/^...|....$//g':। यदि यह हटाने के लिए कुछ वर्णों से अधिक था, तो मैं /.\{17}\/इसके बजाय अभिव्यक्ति का उपयोग करूंगा /.............../
जॉनी

यह खराब व्यवहार करेगा यदि स्ट्रिंग है -eया -n। बेशक, "अंतिम 4 वर्णों को छोड़ दें" का अर्थ 4 वर्णों से छोटे तार के लिए अपरिभाषित है, लेकिन, यदि कोई पहले या अंतिम एक वर्ण को छोड़ने के लिए इसे अनुकूलित करना चाहता है, तो यह उड़ सकता है।
स्कॉट

2

यदि आपके पास एक फ़ाइल है जिसमें हर पंक्ति ग्यारह-वर्ण (या जो भी) स्ट्रिंग है जिसे आप काटना चाहते हैं, sedउपयोग करने का उपकरण है। यह एक एकल स्ट्रिंग में हेरफेर करने के लिए ठीक है, लेकिन यह ओवरकिल है। एक स्ट्रिंग के लिए, जेसन का उत्तर शायद सबसे अच्छा है, यदि आपके पास संस्करण 4.2 या उच्चतर बैश तक पहुंच है। हालाँकि, और वाक्यविन्यास (bash, ksh93, mksh, और zsh) को बैश करने के लिए अद्वितीय प्रतीत होते हैं - मैं उन्हें शेल कमांड लैंग्वेज के लिए ओपन ग्रुप बेस स्पेसिफिकेशन्स में नहीं देखता । यदि आप POSIX- संगत शेल के साथ फंस गए हैं जो विस्तार (निष्कर्षण) के विकल्प का समर्थन नहीं करता है, तो आप उपयोग कर सकते हैं${parameter:offset}${parameter:offset:length}

$ printf "%s\n" "${string#???}"
W2345678

$ printf "%s\n" "${string%????}"
H08W234

printfइसके बजाय echoतार के खिलाफ गार्ड की तरह उपयोग करते हुए abc-e, जहां, जब आप पहले तीन वर्णों को छोड़ते हैं, तो आप के साथ छोड़ दिया जाता है -e (और echo -eवह नहीं है जो आप चाहते हैं)।

और, यदि आप एक बॉर्न-परिवार शेल का उपयोग नहीं कर रहे हैं (या आप एक प्राचीन, पूर्व-पॉसिक्स प्रणाली का उपयोग कर रहे हैं), तो ये अभी भी काम करेंगे:

$ expr " $string" : ' ...\(.*\)'
W2345678

$ expr " $string" : ' \(.*\)....'
H08W234

अतिरिक्त प्रमुख अंतरिक्ष मूल्यों के साथ समस्याओं से बचने के लिए है $string कि वास्तविक हैं exprऑपरेटरों (जैसे, +,  /,  indexया match) या विकल्पों (जैसे,  --, --helpया  --version)।


@ स्टीफन चेज़लस: (1) मुझे उस गड्डे की याद दिलाने के लिए धन्यवाद, जो मैं लगभग 40 साल पहले जानता था और किसी तरह भूलने में कामयाब रहा। (२) मैं हमेशा इसे हल करता था X; जैसे, expr "X$string" : 'X...\(.*\)'। IMO, यह पढ़ना और समझना आसान है। क्या इसके साथ कोई समस्या है, या किसी स्थान को पसंद करने का कोई कारण है? (३) आज मैंने सीखा कि expr + "$string" : '...\(.*\)'अब काम करता है। मुझे याद नहीं है कि 40 साल पहले से; यह पर्याप्त रूप से व्यापक रूप से सिफारिश करने के लिए सुरक्षित होने के लिए उपयोग किया जाता है? (४) आपने जसोनव्रीयन के उत्तर पर एक नोट को याद किया और हेमायल के उत्तर पर एक नाइट-पिक किया।
स्कॉट

AFAIK, जो expr +केवल GNU है (सोलारिस और फ्रीबीएसडी AFAICS पर काम नहीं करेगा)। मैं x के बजाय स्थान का उपयोग करता हूं क्योंकि इसकी संभावना कम है कि कुछ exprकार्यान्वयन में ऐसे ऑपरेटर होंगे जो अंतरिक्ष के साथ शुरू करते हैं xऔर यह भी क्योंकि यह कम संभावना है कि वहाँ collating तत्व होते हैं जो अंतरिक्ष के साथ शुरू होते हैं x। लेकिन तब मुझे एहसास हुआ कि यह expr " $a" "<" " $b"स्ट्रिंग की तुलना के लिए एक अच्छा विकल्प नहीं है क्योंकि कुछ कार्यान्वयन जब संख्याओं की तरह $a/ तुलनात्मक रूप से संख्यात्मक तुलना करते हैं $b। हो सकता है expr "@@$a"...या expr "x $a"सुरक्षित हो सकता है।
स्टीफन चेज़लस

0

साथ में:

string="H08W2345678"

3 या 4 वर्णों का मिलान सरल लगता है (अधिकांश गोले के लिए):

$ printf '%s\t%s\n' "${string#???}" "${string%????}"
W2345678      H08W234

पुराने गोले के लिए (बॉर्न शेल की तरह), उपयोग करें:

$ string=H08W2345678

$ expr " ${string}" : " ...\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\)...." '
H08W234

यदि इसे वर्णों की सांख्यिक गणना की आवश्यकता है, तो उपयोग करें:

$ expr " ${string}" : " .\{3\}\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\).\{4\}" '
H08W234

बेशक, उन regex भी sed, awk और bash 3.0+ के साथ काम करते हैं:

$ echo "$string" | sed 's/^.\{3\}//'
W2345678

$ echo "$string" | sed 's/.\{4\}$//'
H08W234

$ echo "$string" | awk '{sub(/^.{3}/,"")}1'
W2345678

$ echo "$string" | awk '{sub(/.{4}$/,"")}1'
H08W234

$ r='^.{3}(.*)$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
W2345678

$ r='^(.*).{4}$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
H08W234

-1

स्ट्रिंग के सामने से वर्णों को 'ड्रॉप' / डिलीट कैसे करें?

मेरे पास एक स्ट्रिंग है जिसे मैं हेरफेर करना चाहूंगा। स्ट्रिंग H08W2345678 है मैं इसे कैसे हेरफेर कर पाऊंगा ताकि आउटपुट सिर्फ W2345678 हो?

echo "H08W2345678" | cut -c 4-

यह केवल आधे प्रश्न का उत्तर देता है।
Kusalananda

मेरा मानना ​​है कि आपका पतन अनुचित है। इस आधे प्रश्न का उत्तर मुझे तब मिला जब मैंने गोज़लॉइड पोज़िक्स में पहले पात्रों को हटा दिया और इस पृष्ठ ने खोज परिणामों में दिखाया। इसके अलावा, यह पृष्ठ शीर्षक केवल सवाल का आधा हिस्सा कवर करता है। मैं वापस आया और योगदान दिया जब मुझे जो समाधान मिला वह मुझे पसंद आया - मुझे लगता है कि cutइस पृष्ठ पर जो कुछ भी है, उससे कहीं अधिक सुंदर काम है।
aexl
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.