एक अन्य चरित्र के साथ एक स्ट्रिंग में अनुगामी व्हॉट्सएप को पैड करना


12

मैं hello world20 से अधिक पात्रों का उत्पादन करना चाहता हूं ।

printf "%-20s :\n\n" 'hello world!!'

# Actual output
hello world!!        :

# Wanted output
hello world!!========:

हालाँकि, मैं रिक्त स्थान के साथ नहीं बल्कि " = " के साथ पूर्ण करना चाहता हूं । मैं उसको कैसे करू?

जवाबों:


9

अधिक सामान्य समाधान होने के लिए अद्यतित उत्तर। यह भी देखना नीचे मेरी एक और जवाब केवल खोल ब्रेस विस्तार और का उपयोग कर pritnf

$ str='Hello World!'
$ sed -r ':loop; s/ (=*):$/\1=:/; t loop' <<< "$(printf '%-20s:\n' "$str" )"
Hello World!========:

यह काम किस प्रकार करता है?

यह (=*):$/एक स्थान, एक-या-अधिक को कैप्चर करता है जो इसके इनपुट के अंत में =एक बृहदान्त्र द्वारा पीछा करता है :; हम =एक समूह मैच के रूप में सेट करते हैं और \1इसका बैक-रेफरेंस होगा।

जब :loopहमने एक लेबल को परिभाषित किया है loopऔर उसके साथ t loopउस लेबल पर कूद जाएगा जब एक s/ (=*):$/\1=:/सफल प्रतिस्थापन किया है;

के साथ प्रतिस्थापन भाग में \1=:, यह हमेशा =एस की संख्या को बढ़ाएगा और स्ट्रिंग के अंत में बृहदान्त्र को वापस कर देगा।


1
इसलिए आपको इनपुट कितने शब्दों के आधार पर ध्वज को समायोजित करना है?
user1686

@grawity मैंने अब सामान्य समाधान के लिए अपना उत्तर अपडेट कर दिया है।
α atsнιη

20
filler='===================='
string='foo'

printf '%s\n' "$string${filler:${#string}}"

देता है

foo=================

${#string} मूल्य की लंबाई है $string , और ${filler:${#string}}की-स्ट्रिंग है $fillerऑफसेट से ${#string}बाद।

आउटपुट की कुल चौड़ाई अधिकतम चौड़ाई की होगी $filler या उससे अधिक होगी $string

भराव स्ट्रिंग कर सकते हैं, सिस्टम पर jot गतिशील रूप से उपयोग करके बनाया जा सकता है

filler=$( jot -s '' -c 16 '=' '=' )

( =एक पंक्ति में 16 के लिए )। GNU सिस्टम इस्तेमाल कर सकते हैंseq :

filler=$( seq -s '=' 1 16 | tr -dc '=' )

अन्य प्रणालियाँ स्ट्रिंग को गतिशील रूप से बनाने के लिए पर्ल या किसी अन्य तेज़ तरीके का उपयोग कर सकती हैं।


@sddgob printf+ ब्रेस विस्तार के साथ आप इसे कैसे करेंगे bash?
Kusalananda

17
printf "%.20s:\n\n" "$str========================="

जहां %.20sस्ट्रिंग छंटनी प्रारूप है


2
यह IMHO है, मेरा इससे बेहतर उपाय है। यह केवल प्रारूप स्ट्रिंग की एक छोटी व्याख्या की जरूरत है।
Kusalananda

12

इसे करने का एक तरीका:

printf "====================:\r%s\n\n" 'hello world!!'

6
हा! यह एक चतुर चाल है! हालांकि, यह वास्तव में प्रिंट होगा ====================\rhello world, जो एक मुद्दा हो सकता है अगर ओपी को इसे स्टोर करने की जरूरत है और न ही इसे स्क्रीन पर प्रिंट करें।
terdon

भी echo -e '=================\rHello World!!', लेकिन @terdon के रूप में एक ही मुद्दा है कि बताया।
α atsнιη

1
@ αғsнιη केवल अगर echoसमर्थन करता है -e। कई कारणों printfसे लगभग हमेशा बेहतर होता echoहै।
सातु कटुरा

5

एक पर्ल दृष्टिकोण:

$ perl -le '$k="hello world!!"; while(length($k)<20){$k.="=";} print "$k\n"'
hello world!!=======

या, बेहतर, @SatoKatsura ने टिप्पणियों में बताया:

perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'

यदि आपको UTF मल्टी-बाइट वर्णों का समर्थन करने की आवश्यकता है, तो उपयोग करें:

PERL_UNICODE='AS' perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'

शेल में एक ही विचार:

v='hello world!!'; while [ ${#v} -lt 20 ]; do v="$v""="; done; printf '%s\n\n' "$v"

आप एक पाश की जरूरत नहीं है: perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'। हालाँकि, यह (और अब तक पोस्ट किए गए अन्य सभी समाधान) तोड़ता है यदि मल्टी-बाइट वर्ण शामिल हैं।
सातु कटुरा

@ सत्कुत्सुर ऊह, हाँ, यह साफ है! ऐसा सोचना चाहिए था, धन्यवाद। और हाँ, मैं UTF मल्टी-बाइट पात्रों पर संभावित विफलता के लिए एक अस्वीकरण जोड़ने के बारे में सोच रहा था, लेकिन लगा कि यह इस संदर्भ में एक अनावश्यक जटिलता होगी।
टेराडॉन

मुझे लगता है कि perl6मल्टी-बाइट पात्रों के साथ भी इसे सही तरीके से करने का एक तरीका हो सकता है। लेकिन दूसरी तरफ perl6इतने तरीकों से गुस्सा आ रहा है।
सातु कटुरा

@ सत्कुत्सुरा अच्छी तरह से, इस तरह की सरल चीज़ के लिए, बस सेट करने के लिए पर्याप्त होना चाहिए PERL_UNICODE='AS'। उदाहरण के लिए: printf '%s' nóóös | perl -nle 'print length($_)'प्रिंट 8 ("गलत") जबकि printf '%s' nóóös | PERL_UNICODE='AS' perl -nle 'print length($_)'प्रिंट 5 ("सही")।
terdon

5

एक अन्य तरीका केवल printfकमांड का उपयोग कर रहा है और चरित्र पैडिंग पैटर्न को पहले उत्पन्न करता है Shell Brace Expansion(आप एक संख्या ting स्वरूपण क्षेत्र जिसे आप प्रिंट करना चाहते हैं, के साथ समाप्त कर सकते हैं {1..end}) और इसके केवल पहले वर्ण को प्राप्त करें %.1sजो =s है और फिर केवल पहले 20 अक्षरों की लंबाई प्रिंट करें उस का क्षेत्र %.20s। यह दोहराए जाने वाले अक्षरों / शब्दों के बजाय उन्हें नक़ल करने के लिए बेहतर तरीका है।

printf '%.20s:\n' "$str$(printf '%.1s' ={1..20})"
Hello World!!=======:

स्पष्टीकरण:

ब्रेस विस्तार के रूप में आम तौर पर , {1..20}यदि हम इसे प्रिंट करते हैं तो शेल विस्तार के रूप में।

printf '%s ' {1..20}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 

तो इसके साथ एक समान चिह्न जोड़ने के साथ ={1..20}, शेल निम्नलिखित के रूप में विस्तार करेगा।

printf '%s ' ={1..20}
=1 =2 =3 =4 =5 =6 =7 =8 =9 =10 =11 =12 =13 =14 =15 =16 =17 =18 =19 =20 

और साथ printf '%.1s'जो वास्तव में मतलब है printf '%WIDE.LENGTH', हम केवल एक प्रिंट कर रहे हैं लंबाई डिफ़ॉल्ट के साथ ऊपर से उन लोगों में से 1 चौड़ा । तो परिणाम होगा= केवल 20 बार दोहराया जाएगा।

अब printf '%.20s:\n'हम केवल 20 की लंबाई की छपाई कर रहे हैं $strऔर यदि $str<20 की लंबाई है , तो शेष =रिक्त स्थान के बजाय भरने के लिए ले जाएगा ।

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