पाइपिंग बैश स्ट्रिंग हेरफेर


9

मैंने कुछ अन्य पाइपिंग बैश स्ट्रिंग हेरफेर प्रश्न पढ़े हैं, लेकिन वे विशेष अनुप्रयोग प्रतीत होते हैं।

अनिवार्य रूप से, वहाँ नीचे सरल करने के लिए एक रास्ता है?

के बजाय

$ string='hello world'; string2="${string// /_}"; echo "${string2^^}"
HELLO_WORLD

कुछ इस तरह

$ echo 'hello world' | $"{-// /_}" | "${ -^^}"
HELLO_WORLD

अगर मैं गति को बनाए रखने के लिए संभव हो तो बैश जोड़-तोड़ के भीतर रहने में दिलचस्पी रखता हूं (जैसा कि sed / awk के विपरीत जो मेरी लिपियों को बहुत धीमा करने की प्रवृत्ति है)

Edit2: @ जिमीज

मुझे दूसरा उदाहरण पसंद आया और मुझे एक समारोह बनाने के लिए प्रेरित किया।

bash_m() { { read x; echo "${x// /_}"; } | { read x; echo "${x^^}"; }; }
echo hello world | bash_m
HELLO_WORLD

1
आपको क्या लगता है कि इस उद्देश्य के लिए sed / awk धीमा होगा? वे जितनी तेजी से आते हैं।
mcc

1
@ केतन सेड और अवेक अलग-अलग प्रक्रियाएं हैं, इसलिए वे कभी भी तेज नहीं हो सकते हैं क्योंकि बैश एक अलग प्रक्रिया शुरू किए बिना मूल रूप से कर सकते हैं। आम तौर पर यह अंतर शायद ही ध्यान देने योग्य होता है, लेकिन जहां शेल लिपियों में प्रदर्शन मायने रखता है, आमतौर पर एक निश्चित लूप या संगणना कई बार बहुत बड़ी संख्या में दोहराई जाती है, और हजारों प्रक्रियाओं को जन्म देती है, जो मूल रूप से बैश में एक साधारण स्ट्रिंग संकलन करने की तुलना में काफी धीमी होगी।
jw013

2
@ jw013 यह प्रश्न से "हैलो वर्ल्ड" के रूप में छोटे तारों के लिए सच है, लेकिन यदि स्ट्रिंग बहुत लंबी है tr, तो मैनुअल कहें , तो इसके विपरीत सच है क्योंकि प्रक्रियाओं के स्पैनिंग का समय स्ट्रिंग हेरफेर के समय की तुलना में नगण्य है। sedऔर awkसमर्पित हैं। यदि स्ट्रिंग बहुत लंबी है, तो पूरे बैश मैनुअल का कहना है, तो बैश सिर्फ कुछ आंतरिक सीमाओं के कारण, पूरी तरह से आगे बढ़ने से इनकार कर सकता है।
जिमीज

2
@ jw013 मुझे लगता है कि पार्टी के स्ट्रिंग परिवर्तन कोड का दावा कर रहा हूँ के रूप में कम कुशल तो समर्पित उपकरण है sed, awk, trया इसी तरह की। Gena2x उत्तर को देखें, जिसे मैंने कुछ समय पहले इस जानकारी को जोड़ते हुए संपादित किया था: unix.stackexchange.com/questions/162221/… आप इसे टेर्डन जवाब के साथ उसी प्रश्न के साथ तुलना करना चाह सकते हैं जहां वह छोटे तारों के लिए समय देता है जिसमें मामले की प्रक्रिया में ज्यादातर समय लगता है। आप इसे स्वयं परीक्षण कर सकते हैं और परिणाम पोस्ट कर सकते हैं।
जिमीज

1
@Miati आपको क्या लगता है कि यह अतिरिक्त read x; echo $xप्रदर्शन के लिए बेहतर है? वाक्यविन्यास किसी भी छोटे या क्लीनर नहीं दिखता है। x=${x// /_}; x=${x^^}के रूप में एक ही बात करने के लिए एक बहुत अधिक संक्षिप्त तरीका है {read x; echo ${x...। जहां तक प्रदर्शन की बात है, @jimmij ने कहा है कि tr/ sedतेजी से होगा bash, कांटा गिनती बराबर जा रहा है। एक पाइप का उपयोग हमेशा एक अतिरिक्त प्रक्रिया में होता है इसलिए एक कांटा को बचाने का तर्क अब लागू नहीं होता है। इस प्रकार, यदि आप पाइप का उपयोग कर रहे हैं, तो बस का उपयोग करें sed/ trआदि। यदि आप इसे बैश में कर सकते हैं, तो ऐसा करें और इस read x; echo $xबकवास को छोड़ दें ।
jw013

जवाबों:


9

जिमीज ने क्या कहा उसका अंतिम उदाहरण वह निकटतम है जो आप अपने पाइप्ड एक्सप्रेशन में प्राप्त कर रहे हैं।

यहाँ उस विषय पर एक संस्करण है:

echo 'hello world'|echo $(read s;s=${s^^};echo ${s// /_})

मैं उपयोग करने के लिए इच्छुक हूं tr, क्योंकि यह काफी तेज है।

echo 'hello world'|tr ' [:lower:]' '_[:upper:]'

मुझे लगता है कि यह शर्म की बात है कि बैश नेस्टेड पैरामीटर विस्तार की अनुमति नहीं देता है; OTOH, इस तरह के नेस्टेड अभिव्यक्तियों का उपयोग आसानी से कोड के लिए ले जा सकता है जो पढ़ने के लिए दर्दनाक है। जब तक आपको वास्तव में जितनी जल्दी हो सके चीजों को चलाने की आवश्यकता होती है, तो कोड लिखना बेहतर होता है जो कि चतुर-दिखने वाले कोड के बजाय पढ़ने, समझने और बनाए रखने में आसान है, जो कि PITA को डीबग करने के लिए है। और अगर तुम सच में करना शीर्ष गति से किया जा करने की जरूरत बातें आप संकलित कोड, का उपयोग करना चाहिए नहीं एक स्क्रिप्ट।


7

आप इस तरह से पैरामीटर विस्तार पारित नहीं कर सकते। जब आप प्रतीक को रूप में xउपयोग करने के लिए संदर्भित करते हैं , तो यह वास्तविक चर नाम होना चाहिए, न कि एक मानक इनपुट, कम से कम अंदर नहीं । में आप निम्नलिखित तरीके से नेस्टेड पैरामीटर प्रतिस्थापन प्रदर्शन कर सकते हैं:$"${x}"bashzsh

$ x=''hello world'
$ echo ${${x// /_}:u}
HELLO_WORLD

(ध्यान दें: :uके लिए है zshके रूप में ही ^^के लिए bash)

बाश में घोंसला बनाना संभव नहीं है और मुझे लगता है कि आपने प्रश्न में जो लिखा है वह सबसे अच्छा हो सकता है, लेकिन अगर किसी अजीब कारण से आपको पाइप को समीकरण में शामिल करने की आवश्यकता है, तो आप यह कोशिश करना चाह सकते हैं:

$ echo 'hello world' | { read x; echo "${x// /_}"; } | { read y; echo "${y^^}"; }
HELLO_WORLD

1
स्ट्रिंग प्रसंस्करण पर कैसे tr/ sedतेजी से कर रहे हैं के बारे में हमारी हाल की बातचीत को ध्यान में रखते हुए bash, और मानक I / O के माध्यम से तारों को पारित करने के लिए आप पाइप का उपयोग कैसे कर रहे हैं, इस पर विचार करते हुए, मैं शाब्दिक रूप से शून्य में उन कार्यों को करने का विरोध करता हूं जैसे tr/ के विपरीत sed। जो कभी | { read x; echo $x... }विरोध करेगा | sed, वही काम करेगा?
jw013

1
@ jw013 सच कहूं तो मैं बिना किसी बात के आगे देखता हूं। यह सिर्फ एक उदाहरण है जबरदस्ती समस्या के लिए पाइप संलग्न करने के लिए है, क्योंकि ओपी स्पष्ट रूप से (दोनों उनके लिए पूछा और बाहरी प्रोग्राम का उपयोग नहीं करना चाहता था echoऔर readएक छोटा सा तेजी से बैश बनाया-इन कर रहे हैं, सिद्धांत रूप में तो)। जैसा कि मैंने पहले से ही उत्तर प्रगतिशील पैरामीटर जोड़तोड़ में लिखा था जो ओपी के पास प्रश्न में सबसे अच्छा है जो इस कार्य के लिए मेरी राय में मिल सकता है। वैसे भी समस्या बल्कि अकादमिक है।
जिमीज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.