मैं बैश में एक चरित्र कैसे दोहरा सकता हूं?


240

मैं इसके साथ कैसे कर सकता था echo?

perl -E 'say "=" x 100'

अफसोस की बात यह है कि यह बैश नहीं है।
ठोस

1
गूंज के साथ नहीं, लेकिन एक ही विषय पर ruby -e 'puts "=" * 100'याpython -c 'print "=" * 100'
एवगेनी

1
बड़ा सवाल है। बहुत अच्छे जवाब। मैंने यहां एक उत्तर में एक वास्तविक नौकरी का उपयोग किया है, जिसे मैं एक उदाहरण के रूप में पोस्ट करूंगा: github.com/drbeco/oldfiles/blob/master/oldfiles ( printfसाथ में seq)svrb=`printf '%.sv' $(seq $vrb)`
Dr Beco

जो भी (1 या अधिक वर्णों को, यहां तक ​​कि न्यूलाइन्स सहित) मुद्रित करने के लिए एक सामान्य समाधान: रिपीट_थिस () {i = 1; जबकि ["$ i" -le "$ 2"]; प्रिंटफ "% s" "$ 1" करें; i = $ (($ i + 1)); किया हुआ ; प्रिंटफ '\ n' ;; इस तरह का प्रयोग करें: repeat_this "something" Number_of_repetitions। उदाहरण के लिए, 3 newlines सहित 5 बार कुछ दोहराते हुए दिखाने के लिए: Rep_this "$ (printf '\ n \ n \ nthis')" 5। अंतिम प्रिंटफ '\ n' को बाहर निकाला जा सकता है (लेकिन मैंने इसे पाठ फ़ाइलों को बनाने के लिए रखा है, और उन लोगों को अपने अंतिम चरित्र के रूप में एक नई रूपरेखा की आवश्यकता है!)
ओलिवियर दुलैक

जवाबों:


396

आप उपयोग कर सकते हैं:

printf '=%.0s' {1..100}

यह कैसे काम करता है:

बैश का विस्तार {1..100} हो जाता है, ताकि कमांड बन जाए:

printf '=%.0s' 1 2 3 4 ... 100

मैंने प्रिंटफ के प्रारूप को सेट कर दिया है, =%.0sजिसका अर्थ है कि वह हमेशा एक ही प्रिंट करेगा =चाहे वह कितना भी तर्क दे। इसलिए यह 100 =एस प्रिंट करता है ।


14
महान समाधान जो बड़े दोहराने के साथ भी काफी अच्छा प्रदर्शन करता है। यहाँ एक फ़ंक्शन रैपर है, जिसे आप repl = 100उदाहरण के लिए लागू कर सकते हैं (उदाहरण के लिए evalट्रिकरी की आवश्यकता है, दुर्भाग्य से, एक चर पर ब्रेस विस्तार को आधार बनाने के लिए):repl() { printf "$1"'%.s' $(eval "echo {1.."$(($2))"}"); }
mklement0

7
क्या var का उपयोग करके ऊपरी सीमा निर्धारित करना संभव है? मैंने कोशिश की है और यह काम करने के लिए नहीं मिल सकता।
माइक पर्ससेल

70
आप ब्रेस विस्तार के भीतर चर का उपयोग नहीं कर सकते। seqइसके बजाय उदाहरण के लिए उपयोग करें $(seq 1 $limit)
डोगबेन

11
यदि आप इसे क्रियाशील करते हैं तो इसे फिर से व्यवस्थित करना सबसे अच्छा $s%.0sहै %.0s$sअन्यथा डैश एक printfत्रुटि का कारण बनता है ।
कोमोडोवेव

5
इससे मुझे बैश के व्यवहार का पता चला printf: यह तब तक प्रारूप स्ट्रिंग लागू करना जारी रखता है जब तक कि कोई तर्क शेष न हो। मैंने यह मान लिया था कि यह केवल एक बार प्रारूप स्ट्रिंग को संसाधित करेगा!
जीणू Je

89

कोई आसान तरीका नहीं। लेकिन उदाहरण के लिए:

seq -s= 100|tr -d '[:digit:]'

या शायद एक मानक-अनुरूप तरीका:

printf %100s |tr " " "="

वहाँ भी है tput rep, लेकिन हाथ (xterm और linux) पर मेरे टर्मिनलों के लिए के रूप में वे इसे समर्थन नहीं करते :)


3
ध्यान दें कि seq के साथ पहला विकल्प दिए गए संख्या से कम प्रिंट करता है, इसलिए यह उदाहरण 99 =वर्णों को प्रिंट करेगा ।
कैमिलो मार्टिन

13
printf trकेवल POSIX समाधान है क्योंकि seq, yesऔर {1..3}POSIX नहीं हैं।
सिरो सेंटिल्ली 郝海东 冠状 iro i ''

2
केवल एक ही चरित्र के बजाय एक स्ट्रिंग को दोहराने के लिए: printf %100s | sed 's/ /abc/g'- आउटपुट 'एब्काबैबक ...'
जॉन रिक्स

3
कोई छोरों और केवल एक बाहरी कमांड ( tr) का उपयोग करने के लिए +1 । आप इसे कुछ इस तरह बढ़ा सकते हैं printf "%${COLUMNS}s\n" | tr " " "="
मुशीफिल

2
@ mklement0 खैर, मैं उम्मीद कर रहा था कि आप गलती से आखिरी न्यूलाइन गिन रहे थे wc। एकमात्र निष्कर्ष जो मैं इससे ले सकता हूं वह है "का seqउपयोग नहीं किया जाना चाहिए"।
कैमिलो मार्टिन

51

अपने इनपुट के लिए @ gniourf_gniourf को टोपी की टिप दें

नोट: यह उत्तर मूल प्रश्न का उत्तर नहीं देता है , लेकिन प्रदर्शन की तुलना करके मौजूदा, सहायक उत्तरों का पूरक है ।

केवल निष्पादन की गति के संदर्भ में समाधानों की तुलना की जाती है - स्मृति आवश्यकताओं को ध्यान में नहीं रखा जाता है (वे समाधानों में भिन्न होते हैं और बड़े दोहराव के मायने रखते हैं)।

सारांश:

  • यदि आपकी रिपीट गिनती छोटी है , तो लगभग 100 तक बोलें, यह बैश-केवल समाधानों के साथ जाने योग्य है , क्योंकि बाहरी उपयोगिताओं के स्टार्टअप की लागत, विशेष रूप से पर्ल की।
    • व्यावहारिक रूप से बोलना, हालांकि, यदि आपको केवल दोहराए जाने वाले वर्णों की एक आवृत्ति की आवश्यकता है, तो सभी मौजूदा समाधान ठीक हो सकते हैं।
  • बड़े दोहराने के साथ , बाहरी उपयोगिताओं का उपयोग करें , क्योंकि वे बहुत तेज़ होंगे।
    • विशेष रूप से, बड़े स्ट्रिंग्स
      (जैसे ${var// /=}) के साथ बैश के वैश्विक प्रतिस्थापन प्रतिस्थापन से बचें , क्योंकि यह निषेधात्मक रूप से धीमा है।

निम्नलिखित हैं समय एक 3.2 गीगा इंटेल कोर i5 सीपीयू और एक फ्यूजन ड्राइव, OSX 10.10.4 और बैश 3.2.57 चल के साथ एक देर से 2012 आईमैक पर ले लिया है, और 1000 रन की औसत रहे हैं।

प्रविष्टियां हैं:

  • निष्पादन अवधि के आरोही क्रम में सूचीबद्ध (सबसे पहले)
  • इसके साथ उपसर्ग:
    • M... एक संभावित बहु -वर्ण समाधान
    • S... एक एकल -एकमात्र समाधान
    • P ... एक POSIX- अनुरूप समाधान
  • समाधान का एक संक्षिप्त विवरण के बाद
  • मूल उत्तर के लेखक के नाम के साथ प्रत्यय लगा है

  • छोटी रिपीट गिनती: 100
[M, P] printf %.s= [dogbane]:                           0.0002
[M   ] printf + bash global substr. replacement [Tim]:  0.0005
[M   ] echo -n - brace expansion loop [eugene y]:       0.0007
[M   ] echo -n - arithmetic loop [Eliah Kagan]:         0.0013
[M   ] seq -f [Sam Salisbury]:                          0.0016
[M   ] jot -b [Stefan Ludwig]:                          0.0016
[M   ] awk - $(count+1)="=" [Steven Penny (variant)]:   0.0019
[M, P] awk - while loop [Steven Penny]:                 0.0019
[S   ] printf + tr [user332325]:                        0.0021
[S   ] head + tr [eugene y]:                            0.0021
[S, P] dd + tr [mklement0]:                             0.0021
[M   ] printf + sed [user332325 (comment)]:             0.0021
[M   ] mawk - $(count+1)="=" [Steven Penny (variant)]:  0.0025
[M, P] mawk - while loop [Steven Penny]:                0.0026
[M   ] gawk - $(count+1)="=" [Steven Penny (variant)]:  0.0028
[M, P] gawk - while loop [Steven Penny]:                0.0028
[M   ] yes + head + tr [Digital Trauma]:                0.0029
[M   ] Perl [sid_com]:                                  0.0059
  • बैश-केवल समाधान पैक का नेतृत्व करते हैं - लेकिन केवल एक दोहराने के साथ यह छोटा होता है! (निचे देखो)।
  • बाहरी उपयोगिताओं की स्टार्टअप लागत यहां मायने रखती है, विशेष रूप से पर्ल की। यदि आप इसे लूप में कहते हैं - प्रत्येक पुनरावृत्ति में छोटे पुनरावृत्ति मायने रखता है - बहु-उपयोगिता awk, और perlसमाधान से बचें ।

  • बड़ी दोहराने की गिनती: 1000000 (1 मिलियन)
[M   ] Perl [sid_com]:                                  0.0067
[M   ] mawk - $(count+1)="=" [Steven Penny (variant)]:  0.0254
[M   ] gawk - $(count+1)="=" [Steven Penny (variant)]:  0.0599
[S   ] head + tr [eugene y]:                            0.1143
[S, P] dd + tr [mklement0]:                             0.1144
[S   ] printf + tr [user332325]:                        0.1164
[M, P] mawk - while loop [Steven Penny]:                0.1434
[M   ] seq -f [Sam Salisbury]:                          0.1452
[M   ] jot -b [Stefan Ludwig]:                          0.1690
[M   ] printf + sed [user332325 (comment)]:             0.1735
[M   ] yes + head + tr [Digital Trauma]:                0.1883
[M, P] gawk - while loop [Steven Penny]:                0.2493
[M   ] awk - $(count+1)="=" [Steven Penny (variant)]:   0.2614
[M, P] awk - while loop [Steven Penny]:                 0.3211
[M, P] printf %.s= [dogbane]:                           2.4565
[M   ] echo -n - brace expansion loop [eugene y]:       7.5877
[M   ] echo -n - arithmetic loop [Eliah Kagan]:         13.5426
[M   ] printf + bash global substr. replacement [Tim]:  n/a
  • प्रश्न से पर्ल समाधान सबसे तेजी से दूर है।
  • बैश का ग्लोबल स्ट्रिंग-रिप्लेसमेंट ( ${foo// /=}) बेवजह बड़े स्ट्रिंग्स के साथ धीमी गति से होता है, और बैश 4.3.30 में (लगभग 50 मिनट!) रनिंग से बाहर ले जाया गया है, और बैश 3.2.57 में भी लंबे समय तक! मैंने कभी इंतजार नहीं किया। इसे समाप्त करना)।
  • बैश लूप्स धीमे होते हैं, और अंकगणित लूप ( (( i= 0; ... ))) ब्रेस-विस्तारित वाले की तुलना में धीमे होते हैं ( {1..n}) - हालांकि अंकगणितीय लूप अधिक मेमोरी-कुशल होते हैं।
  • awkबीएसडी को संदर्भित करता है awk(जैसा कि OSX पर भी पाया गया है) - यह gawk(GNU Awk) की तुलना में विशेष रूप से धीमा है और विशेष रूप से mawk
  • ध्यान दें कि बड़े काउंट और मल्टी-चार के साथ। तार, स्मृति की खपत एक विचार बन सकती है - दृष्टिकोण उस संबंध में भिन्न होते हैं।

यहाँ बैश लिपि ( testrepeat) है जो उपरोक्त उत्पादन करती है। इसमें 2 तर्क दिए गए हैं:

  • चरित्र दोहराने गिनती
  • वैकल्पिक रूप से, प्रदर्शन करने के लिए और औसत समय की गणना करने के लिए परीक्षण की संख्या चलती है

दूसरे शब्दों में: ऊपर दिए गए समय के साथ testrepeat 100 1000और प्राप्त किए गए थेtestrepeat 1000000 1000

#!/usr/bin/env bash

title() { printf '%s:\t' "$1"; }

TIMEFORMAT=$'%6Rs'

# The number of repetitions of the input chars. to produce
COUNT_REPETITIONS=${1?Arguments: <charRepeatCount> [<testRunCount>]}

# The number of test runs to perform to derive the average timing from.
COUNT_RUNS=${2:-1}

# Discard the (stdout) output generated by default.
# If you want to check the results, replace '/dev/null' on the following
# line with a prefix path to which a running index starting with 1 will
# be appended for each test run; e.g., outFilePrefix='outfile', which
# will produce outfile1, outfile2, ...
outFilePrefix=/dev/null

{

  outFile=$outFilePrefix
  ndx=0

  title '[M, P] printf %.s= [dogbane]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  # !! In order to use brace expansion with a variable, we must use `eval`.
  eval "
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    printf '%.s=' {1..$COUNT_REPETITIONS} >"$outFile"
  done"

  title '[M   ] echo -n - arithmetic loop [Eliah Kagan]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    for ((i=0; i<COUNT_REPETITIONS; ++i)); do echo -n =; done >"$outFile"
  done


  title '[M   ] echo -n - brace expansion loop [eugene y]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  # !! In order to use brace expansion with a variable, we must use `eval`.
  eval "
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    for i in {1..$COUNT_REPETITIONS}; do echo -n =; done >"$outFile"
  done
  "

  title '[M   ] printf + sed [user332325 (comment)]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    printf "%${COUNT_REPETITIONS}s" | sed 's/ /=/g' >"$outFile"
  done


  title '[S   ] printf + tr [user332325]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    printf "%${COUNT_REPETITIONS}s" | tr ' ' '='  >"$outFile"
  done


  title '[S   ] head + tr [eugene y]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    head -c $COUNT_REPETITIONS < /dev/zero | tr '\0' '=' >"$outFile"
  done


  title '[M   ] seq -f [Sam Salisbury]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    seq -f '=' -s '' $COUNT_REPETITIONS >"$outFile"
  done


  title '[M   ] jot -b [Stefan Ludwig]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    jot -s '' -b '=' $COUNT_REPETITIONS >"$outFile"
  done


  title '[M   ] yes + head + tr [Digital Trauma]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    yes = | head -$COUNT_REPETITIONS | tr -d '\n'  >"$outFile"
  done

  title '[M   ] Perl [sid_com]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    perl -e "print \"=\" x $COUNT_REPETITIONS" >"$outFile"
  done

  title '[S, P] dd + tr [mklement0]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  time for (( n = 0; n < COUNT_RUNS; n++ )); do 
    dd if=/dev/zero bs=$COUNT_REPETITIONS count=1 2>/dev/null | tr '\0' "=" >"$outFile"
  done

  # !! On OSX, awk is BSD awk, and mawk and gawk were installed later.
  # !! On Linux systems, awk may refer to either mawk or gawk.
  for awkBin in awk mawk gawk; do
    if [[ -x $(command -v $awkBin) ]]; then

      title "[M   ] $awkBin"' - $(count+1)="=" [Steven Penny (variant)]'
      [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
      time for (( n = 0; n < COUNT_RUNS; n++ )); do 
        $awkBin -v count=$COUNT_REPETITIONS 'BEGIN { OFS="="; $(count+1)=""; print }' >"$outFile"
      done

      title "[M, P] $awkBin"' - while loop [Steven Penny]'
      [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
      time for (( n = 0; n < COUNT_RUNS; n++ )); do 
        $awkBin -v count=$COUNT_REPETITIONS 'BEGIN { while (i++ < count) printf "=" }' >"$outFile"
      done

    fi
  done

  title '[M   ] printf + bash global substr. replacement [Tim]'
  [[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
  # !! In Bash 4.3.30 a single run with repeat count of 1 million took almost
  # !! 50 *minutes*(!) to complete; n Bash 3.2.57 it's seemingly even slower -
  # !! didn't wait for it to finish.
  # !! Thus, this test is skipped for counts that are likely to be much slower
  # !! than the other tests.
  skip=0
  [[ $BASH_VERSINFO -le 3 && COUNT_REPETITIONS -gt 1000 ]] && skip=1
  [[ $BASH_VERSINFO -eq 4 && COUNT_REPETITIONS -gt 10000 ]] && skip=1
  if (( skip )); then
    echo 'n/a' >&2
  else
    time for (( n = 0; n < COUNT_RUNS; n++ )); do 
      { printf -v t "%${COUNT_REPETITIONS}s" '='; printf %s "${t// /=}"; } >"$outFile"
    done
  fi
} 2>&1 | 
 sort -t$'\t' -k2,2n | 
   awk -F $'\t' -v count=$COUNT_RUNS '{ 
    printf "%s\t", $1; 
    if ($2 ~ "^n/a") { print $2 } else { printf "%.4f\n", $2 / count }}' |
     column -s$'\t' -t

समय की तुलना देखना दिलचस्प है, लेकिन मुझे लगता है कि कई कार्यक्रमों में आउटपुट बफ़र किया जाता है, इसलिए बफ़रिंग को बंद कर दिया गया तो उनके समय में बदलाव किया जा सकता है।
सर्गी कोलोडियाज़नी

In order to use brace expansion with a variable, we must use `eval`B
pyb

2
तो पेरल सॉल्यूशन (साइड_कॉम) मूल रूप से सबसे तेज है ... एक बार लॉन्चिंग पर्ल के शुरुआती ओवरहेड तक पहुंच जाता है। (यह एक छोटे से रिपीट के लिए 59 मिलियन से 67 मिलियन तक जाता है ... एक दोहराव के लिए ... इसलिए पर्ल फोर्किंग ने आपके सिस्टम पर लगभग 59ms ले लिया)
ओलिवियर

46

इसे करने का एक से अधिक तरीका है।

एक लूप का उपयोग करना:

  • ब्रेस विस्तार का उपयोग पूर्णांक शाब्दिक के साथ किया जा सकता है:

    for i in {1..100}; do echo -n =; done    
  • C- जैसा लूप वैरिएबल के उपयोग की अनुमति देता है:

    start=1
    end=100
    for ((i=$start; i<=$end; i++)); do echo -n =; done

printfबिलिन का उपयोग करना :

printf '=%.0s' {1..100}

यहां एक सटीक निर्दिष्ट करना निर्दिष्ट चौड़ाई ( 0) को फिट करने के लिए स्ट्रिंग को काटता है । जैसा कि printfसभी तर्कों का उपभोग करने के लिए प्रारूप स्ट्रिंग का पुन: उपयोग होता है, यह केवल "="100 बार प्रिंट करता है।

का उपयोग कर head(और printf,) और tr:

head -c 100 < /dev/zero | tr '\0' '='
printf %100s | tr " " "="

2
++ के लिए head/ trसमाधान, जो उच्च दोहराने वाली गणनाओं के साथ भी अच्छी तरह से काम करता है (छोटा चेतावनी: head -cपोसिक्स-अनुपालन नहीं है, लेकिन बीएसडी और जीएनयू दोनों headइसे लागू करते हैं); जबकि उस मामले में अन्य दो समाधान धीमी गति से होंगे, उनके पास मल्टी- स्ट्रैचर स्ट्रिंग्स के साथ काम करने का लाभ भी है।
mklement0

1
यदि आप एक निश्चित संख्या में नई सुर्खियों का उपयोग कर रहे हैं yesऔर headउपयोगी है yes "" | head -n 100:। trकिसी भी चरित्र को मुद्रित कर सकते हैं:yes "" | head -n 100 | tr "\n" "="; echo
loxaxs

कुछ आश्चर्य की बात है: संस्करण dd if=/dev/zero count=1 bs=100000000 | tr '\0' '=' >/dev/nullकी तुलना में काफी धीमी है head -c100000000 < /dev/zero | tr '\0' '=' >/dev/null। निश्चित रूप से समय अंतर को यथोचित रूप से मापने के लिए आपको 100M + के ब्लॉक आकार का उपयोग करना होगा। 100M बाइट्स दिखाए गए दो संबंधित संस्करणों के साथ 1.7 s और 1 s लेता है। मैंने ट्राई को उतार दिया और बस इसे डंप कर दिया /dev/nullऔर headसंस्करण के लिए 0.287 और ddएक बिलियन बाइट्स के लिए संस्करण के लिए 0.675 एस प्राप्त किया ।
माइकल गोल्डस्मीन

के लिए: dd if=/dev/zero count=1 bs=100000000 | tr '\0' '=' >/dev/null=> 0,21332 s, 469 MB/s; के लिए: dd if=/dev/zero count=100 bs=1000000| tr '\0' '=' >/dev/null=> 0,161579 s, 619 MB/s;
3ED

31

मैं बस seq का उपयोग कर यह करने के लिए एक गंभीरता से आसान तरीका मिल गया है:

अद्यतन: यह बीएसडी पर काम करता है जो seqअन्य संस्करणों के साथ ओएस एक्स वाईएमएमवी के साथ आता है

seq  -f "#" -s '' 10

इस तरह 10 बार '#' प्रिंट करेंगे:

##########
  • -f "#"संख्याओं को अनदेखा करने के लिए प्रारूप स्ट्रिंग सेट करता है और बस #प्रत्येक के लिए प्रिंट करता है।
  • -s '' प्रत्येक नंबर के बीच आवेषण seq आवेषण को निकालने के लिए विभाजक को एक रिक्त स्ट्रिंग में सेट करता है
  • के बाद रिक्त स्थान -fऔर -sमहत्वपूर्ण होने लगते हैं।

संपादित करें: यहाँ यह एक आसान कार्य में है ...

repeat () {
    seq  -f $1 -s '' $2; echo
}

जिसे आप इस तरह से कॉल कर सकते हैं ...

repeat "#" 10

नोट: यदि आप दोहरा रहे हैं #तो उद्धरण महत्वपूर्ण हैं!


7
यह मुझे देता है seq: format ‘#’ has no % directiveseqसंख्या के लिए है, तार नहीं। Gnu.org/software/coreutils/manual/html_node/seq-invocation.html
John B

आह, इसलिए मैं ओएस एक्स पर पाया seq के बीएसडी संस्करण का उपयोग कर रहा था। मैं जवाब को अपडेट करूंगा। आपके द्वारा कौन सा संस्करण उपयोग किया जा रहा है?
सैम सैलिसबरी

मैं GNU कोरुटिल से seq का उपयोग कर रहा हूँ।
जॉन बी

1
@JohnB: स्ट्रिंग्स को दोहराने के लिए बीएसडी seqको यहां चतुराई से दोहराया जा रहा है : प्रारूप स्ट्रिंग को पास किया गया - सामान्य रूप से उत्पन्न होने वाली संख्याओं को प्रारूपित करने के लिए उपयोग किया जाता है - यहां केवल स्ट्रिंग को दोहराने के लिए होता है ताकि आउटपुट में केवल उस स्ट्रिंग की प्रतियां शामिल हों। दुर्भाग्य से, GNU प्रारूप स्ट्रिंग में एक संख्या प्रारूप की उपस्थिति पर जोर देता है , जो कि आप देख रहे त्रुटि है। -fseq
mklement0

1
अच्छी तरह से किया; मल्टी- स्ट्रैचर स्ट्रिंग्स के साथ भी काम करता है । कृपया "$1"(दोहरे उद्धरण चिह्नों) का उपयोग करें , ताकि आप वर्णों में भी पास हो सकें '*'और एम्बेडेड व्हाट्सएप के साथ तार कर सकें । अंत में, यदि आप उपयोग करने के लिए सक्षम होना चाहते हैं %, तो आप के लिए है दोगुना यह (अन्यथा seqहोगा लगता है कि यह इस तरह के रूप में एक प्रारूप विनिर्देश का हिस्सा %f); का उपयोग कर "${1//%/%%}"ध्यान रखना होगा। चूंकि (जैसा कि आप उल्लेख करते हैं) आप बीएसडी का उपयोग कर रहे हैं seq, यह सामान्य रूप से बीएसडी जैसे ओएस पर काम करेगा (उदाहरण के लिए, फ्रीबीएसडी) - इसके विपरीत, यह लिनक्स पर काम नहीं करेगा , जहां जीएनयू seq का उपयोग किया जाता है।
mklement0

18

यहाँ दो दिलचस्प तरीके हैं:

ubuntu @ ubuntu: ~ $ हां = | सिर -10 | पेस्ट -s -d '' -
==========
ubuntu @ ubuntu: ~ $ हां = | सिर -10 | tr -d "\ n"
========== ubuntu @ ubuntu: ~ $ 

ध्यान दें कि ये दोनों अलग-अलग हैं - pasteविधि एक नई पंक्ति में समाप्त होती है। trविधि नहीं है।


1
अच्छी तरह से किया; कृपया ध्यान दें कि एक खाली सीमांकक को निर्दिष्ट करने के लिए बीएसडी को paste अनिवार्य रूप से आवश्यकता होती -d '\0'है, और इसके साथ विफल हो जाता है -d ''- -d '\0'सभी पोसिक्स-संगत pasteकार्यान्वयनों को काम करना चाहिए और वास्तव में जीएनयू के साथ pasteभी काम करना चाहिए।
mklement0

आत्मा में समान, कम आउटबोर्ड टूल के साथ:yes | mapfile -n 100 -C 'printf = \#' -c 1
बिशप

@ बिशप: जबकि आपकी कमान वास्तव में एक कम उपधारा बनाती है, यह अभी भी उच्च दोहराने वाले काउंट्स के लिए धीमी है, और कम दोहराने के लिए यह अंतर मायने रखता है कि शायद कोई फर्क नहीं पड़ता; सटीक सीमा शायद हार्डवेयर और ओएस-निर्भर दोनों है, उदाहरण के लिए, मेरे OSX 10.11.5 मशीन पर यह उत्तर पहले से ही 500 पर तेज है; कोशिश करो time yes = | head -500 | paste -s -d '\0' -; time yes | mapfile -n 500 -C 'printf = \#' -c 1। अधिक महत्वपूर्ण बात, हालांकि: यदि आप किसी printfभी तरह का उपयोग कर रहे हैं , तो आप स्वीकार किए गए उत्तर से दोनों सरल और अधिक कुशल दृष्टिकोण के साथ जा सकते हैं:printf '%.s=' $(seq 500)
mklement0

13

कोई सरल तरीका नहीं है। उपयोग printfऔर प्रतिस्थापन से छोरों से बचें ।

str=$(printf "%40s")
echo ${str// /rep}
# echoes "rep" 40 times.

2
अच्छा है, लेकिन केवल छोटे रिपीट काउंट्स के साथ यथोचित प्रदर्शन करता है। यहाँ एक फ़ंक्शन आवरण है जिसे repl = 100उदाहरण के लिए, (एक अनुगामी आउटपुट नहीं है \n) के रूप में लागू किया जा सकता है :repl() { local ts=$(printf "%${2}s"); printf %s "${ts// /$1}"; }
mklement0

1
@ mklement0 दोनों समाधानों के फ़ंक्शन संस्करण प्रदान करने के लिए आपको अच्छा लगा, दोनों पर +1!
कैमिलो मार्टिन

8

यदि आप POSIX- अनुपालन और निरंतरता के विभिन्न कार्यान्वयनों में echoऔर printf, और / या केवल के अलावा अन्य गोले चाहते हैं bash:

seq(){ n=$1; while [ $n -le $2 ]; do echo $n; n=$((n+1)); done ;} # If you don't have it.

echo $(for each in $(seq 1 100); do printf "="; done)

... उत्पादन के perl -E 'say "=" x 100'बारे में हर जगह के रूप में ही उत्पादन होगा ।


1
समस्या यह है कि seqएक पॉसिक्स उपयोगिता नहीं है (हालांकि बीएसडी और लिनक्स सिस्टम के पास इसके कार्यान्वयन हैं) - आप while@ Xennex81 के उत्तर में (जैसे printf "=", जैसा कि आप सही ढंग से सुझाव देते हैं, बजाय echo -n) , लूप के साथ पॉसिक्स शेल अंकगणित कर सकते हैं ।
mklement0

1
ओह, आप काफी सही हैं। इस तरह की चीजें मुझे कभी-कभी मेरे अतीत से अलग कर देती हैं क्योंकि यह मानक कोई गलत अर्थ नहीं रखता है। calPOSIX है। seqनहीं है। वैसे भी, थोड़ी देर के पाश के साथ उत्तर को फिर से लिखने के बजाय (जैसा कि आप कहते हैं, यह पहले से ही अन्य उत्तरों में है) मैं एक RYO फ़ंक्शन जोड़ूंगा। इस तरह से अधिक शैक्षिक ;-)।
ज्योफ निक्सन

8

सवाल यह था कि इसे कैसे किया जाए echo:

echo -e ''$_{1..100}'\b='

यह ठीक वैसा ही करेगा, perl -E 'say "=" x 100'लेकिन echoकेवल उसी के साथ ।


अब यह असामान्य है, अगर आप इसमें अतिरिक्त स्पेस-बैकस्पेस नहीं डालते हैं .. या इसका उपयोग करके साफ करें: इको-$ $ _ {1..100} '\ b =' | col
anthony

1
बुरा विचार। यह अगर असफल हो जायेगी $_1, $_2या सौ चर के किसी भी अन्य मान हैं।
जॉन कुगेलमैन

@ जोहानुगेलमैन गूंज $ (सेट - eval इको-ई \ _ $ {{1..100}} '\\ b =')
mug896

यह स्थूल है । मुझे यह पसंद है: D
dimo414

6

कोई नहीं eval, कोई उपधारा, कोई बाहरी उपकरण, कोई ब्रेस विस्तार (यानी, आपके पास चर में दोहराने के लिए संख्या हो सकती है) के साथ एक शुद्ध बैश रास्ता :

यदि आपको एक चर दिया जाता है nजो एक (गैर-ऋणात्मक) संख्या और एक चर pattern, जैसे,

$ n=5
$ pattern=hello
$ printf -v output '%*s' "$n"
$ output=${output// /$pattern}
$ echo "$output"
hellohellohellohellohello

आप इसके साथ एक फंक्शन कर सकते हैं:

repeat() {
    # $1=number of patterns to repeat
    # $2=pattern
    # $3=output variable name
    local tmp
    printf -v tmp '%*s' "$1"
    printf -v "$3" '%s' "${tmp// /$2}"
}

इस सेट के साथ:

$ repeat 5 hello output
$ echo "$output"
hellohellohellohellohello

इस छोटी सी ट्रिक के लिए हम इसके printfसाथ काफी प्रयोग कर रहे हैं :

  • -v varname: मानक आउटपुट पर मुद्रण के बजाय, printfस्वरूपित स्ट्रिंग की सामग्री को चर में डाल देगा varname
  • '% * s': printfरिक्त स्थान की संबंधित संख्या को मुद्रित करने के लिए तर्क का उपयोग करेगा। जैसे, printf '%*s' 42४२ स्थान छपेंगे।
  • अंत में, जब हमारे पास हमारे चर में रिक्त स्थान की संख्या है, तो हम अपने पैटर्न द्वारा सभी रिक्त स्थान को बदलने के लिए एक पैरामीटर विस्तार का उपयोग करते हैं: के विस्तार से प्रतिस्थापित सभी रिक्त स्थान ${var// /$pattern}के varसाथ विस्तार होगा $pattern

आप अप्रत्यक्ष विस्तार का उपयोग करके फ़ंक्शन tmpमें चर से छुटकारा पा सकते हैं repeat:

repeat() {
    # $1=number of patterns to repeat
    # $2=pattern
    # $3=output variable name
    printf -v "$3" '%*s' "$1"
    printf -v "$3" '%s' "${!3// /$2}"
}

चर नाम में पास करने के लिए दिलचस्प भिन्नता। जबकि यह समाधान लगभग 1,000 तक की गिनती के लिए ठीक है (और इस तरह शायद अधिकांश वास्तविक जीवन के अनुप्रयोगों के लिए ठीक है, अगर मुझे लगता है), तो यह उच्च गणना के लिए बहुत धीमा हो जाता है (आगे देखें टिप्पणी)।
mklement0

ऐसा लगता है कि bashपैरामीटर विस्तार ( ${var//old/new}) के संदर्भ में वैश्विक स्ट्रिंग प्रतिस्थापन ऑपरेशन विशेष रूप से धीमे हैं: बैश 3.2.57में धीरे-धीरे धीमी गति से और बैश में धीमी गति से 4.3.30, कम से कम मेरे OSX 10.10.3 सिस्टम पर 3.2 Ghz इंटेल कोर i5 मशीन पर। 1,000 की गिनती, चीजें धीमी हैं ( 3.2.57) / तेज ( 4.3.30): 0.1 / 0.004 सेकंड। संख्या में 10,000 पैदावार बढ़ाने के लिए अलग-अलग संख्या में: repeat 10000 = varलगभग 80 सेकंड (!) को bash में 3.2.57, और लगभग 0.3 सेकंड को bash में 4.3.30(बहुत तेज़ी से 3.2.57, लेकिन फिर भी धीमा)।
mklement0

6
#!/usr/bin/awk -f
BEGIN {
  OFS = "="
  NF = 100
  print
}

या

#!/usr/bin/awk -f
BEGIN {
  while (z++ < 100) printf "="
}

उदाहरण


3
अच्छी तरह से किया; यह POSIX- अनुरूप है और यथोचित रूप से उच्च पुनरावृत्ति की गिनती के साथ भी तेज है, जबकि बहु-वर्ण स्ट्रिंग्स का समर्थन भी करता है। यहाँ शेल संस्करण है awk 'BEGIN { while (c++ < 100) printf "=" }':। एक पैरामीटर किए गए शेल फ़ंक्शन में लिपटे ( repeat 100 =उदाहरण के लिए, इनवोक करें ) repeat() { awk -v count="$1" -v txt=".$2" 'BEGIN { txt=substr(txt, 2); while (i++ < count) printf txt }'; }:। (डमी .उपसर्ग चार और पूरक substrकॉल बीएसडी में एक बग के आसपास काम करने के लिए आवश्यक है awk, जहां एक चर मान है जो कमांड को तोड़ने के साथ शुरू होता है= ।)
mklement0

1
NF = 100समाधान (हालांकि 100 पाने के लिए बहुत चालाक है =, आप का उपयोग करना चाहिए NF = 101)। चेतावनी यह है कि यह BSD को क्रैश कर देता है awk(लेकिन यह बहुत तेज़ है gawkऔर इसके साथ और भी तेज़ है mawk), और यह कि POSIX न तो असाइनमेंट करता है NF, न ही BEGINब्लॉकों में खेतों का उपयोग करता है । आप इसे बीएसडी के awkसाथ-साथ एक मामूली ट्वीक के साथ भी बना सकते हैं : awk 'BEGIN { OFS = "="; $101=""; print }'(लेकिन उत्सुकता से, बीएसडी में awkजो लूप समाधान से तेज नहीं है)। एक पैरामीटर शेल समाधान के रूप में repeat() { awk -v count="$1" -v txt=".$2" 'BEGIN { OFS=substr(txt, 2); $(count+1)=""; print }'; }:।
mklement0

उपयोगकर्ताओं पर ध्यान दें - NF = 100 चाल पुराने awk पर एक खंड दोष का कारण बनती है। original-awkबीएसडी के awk, जो भी, क्रैश हुआ हो तो आप इस कोशिश करना चाहते हैं सूचित किया गया है के लिए इसी तरह पुराने awk का लिनक्स के तहत नाम है। ध्यान दें कि दुर्घटनाग्रस्त होना आमतौर पर एक शोषक बग को खोजने की दिशा में पहला कदम है। यह उत्तर असुरक्षित कोड को बढ़ावा दे रहा है।

2
उपयोगकर्ताओं के लिए ध्यान दें - original-awkगैर मानक है और अनुशंसित नहीं है
स्टीवन पेनी

पहले कोड स्निपेट का एक विकल्प हो सकता है awk NF=100 OFS='=' <<< ""(उपयोग करना bashऔर gawk)
oliv

4

मुझे लगता है कि प्रश्न का मूल उद्देश्य केवल शेल के अंतर्निहित कमांड के साथ ऐसा करना था। तो forछोरों और printfरों, वैध होगा, जबकि rep, perl, और भी jotनीचे नहीं होगा। फिर भी, निम्नलिखित आदेश

jot -s "/" -b "\\" $((COLUMNS/2))

उदाहरण के लिए, खिड़की की चौड़ी लाइन प्रिंट करता है \/\/\/\/\/\/\/\/\/\/\/\/


2
अच्छी तरह से किया; यह उच्च रिपीट काउंट (बहु-चरित्र स्ट्रिंग्स का समर्थन करते हुए) के साथ भी अच्छा काम करता है। दृष्टिकोण को बेहतर ढंग से समझने के लिए, यहाँ ओपी के आदेश के बराबर है jot -s '' -b '=' 100:। चेतावनी यह है कि BSD जैसे प्लेटफॉर्म, OSX सहित jot, लिनक्स डिस्ट्रोस के साथ नहीं आते हैं
mklement0

1
धन्यवाद, मुझे आपके '-s' का प्रयोग और भी अच्छा लगता है। मैंने अपनी स्क्रिप्ट बदल दी है।
स्टीफन लुडविग

हाल ही में डेबियन- आधारित प्रणालियों पर, apt install athena-jotप्रदान करेगा jot
20

4

जैसा कि अन्य लोगों ने कहा है, बैश ब्रेस में एक्सपोज़र पैरामीटर विस्तार से पहले होता है , इसलिए रेंज में केवल शाब्दिक शामिल हो सकते हैं। और स्वच्छ समाधान प्रदान करते हैं, लेकिन एक सिस्टम से दूसरे सिस्टम में पूरी तरह से पोर्टेबल नहीं हैं, भले ही आप प्रत्येक पर समान शेल का उपयोग कर रहे हों। (हालांकि तेजी से उपलब्ध है, उदाहरण के लिए, FreeBSD 9.3 और उच्चतर में ।) और अप्रत्यक्ष के अन्य रूप हमेशा काम करते हैं, लेकिन कुछ हद तक असंगत हैं।{m,n}seqjotseqeval

सौभाग्य से, बैश छोरों के लिए सी-शैली का समर्थन करता है (केवल अंकगणितीय अभिव्यक्तियों के साथ)। तो यहाँ एक संक्षिप्त "शुद्ध बैश" तरीका है:

repecho() { for ((i=0; i<$1; ++i)); do echo -n "$2"; done; echo; }

यह पहले तर्क के रूप में दोहराव की संख्या लेता है और दूसरे तर्क के रूप में दोहराया जाने वाला स्ट्रिंग (जो एकल वर्ण हो सकता है, जैसा कि समस्या वर्णन में है)। repecho 7 bआउटपुट bbbbbbb(एक नई लाइन द्वारा समाप्त)।

डेनिस विलियमसन दिया अनिवार्य रूप से अपने उत्कृष्ट जवाब में चार साल पहले इस समाधान के लिए खोल स्क्रिप्ट में दोहराया वर्णों की स्ट्रिंग बनाना । मेरा फ़ंक्शन बॉडी वहां के कोड से थोड़ा अलग है:

  • चूँकि यहाँ ध्यान एक ही चरित्र को दोहराने पर है और शेल बैश है, इसलिए संभवतः echoइसके बजाय इसका उपयोग करना सुरक्षित है printf। और मैंने इस प्रश्न में समस्या के वर्णन को पढ़ने के लिए प्राथमिकता दी है echo। उपरोक्त फ़ंक्शन परिभाषा बैश और ksh93 में काम करती है । यद्यपि printfअधिक पोर्टेबल है (और आमतौर पर इस तरह की चीज के लिए इस्तेमाल किया जाना चाहिए), echoवाक्यविन्यास यकीनन अधिक पठनीय है।

    कुछ गोले का निर्माण अपने आप में एक विकल्प के रूप में echoव्याख्या -करता है - भले ही -इनपुट के लिए स्टड का उपयोग करने का सामान्य अर्थ , के लिए बकवास है echozsh यह करता है। और निश्चित रूप से मौजूद है echoकि यह पहचान नहीं है -n, क्योंकि यह मानक नहीं है । (कई बॉर्न-शैली के गोले छोरों के लिए सी-शैली को बिल्कुल स्वीकार नहीं करते हैं, इस प्रकार उनके echoव्यवहार पर विचार नहीं किया जाना चाहिए ..)

  • यहां कार्य अनुक्रम को प्रिंट करना है; वहाँ , यह एक चर के लिए आवंटित करने के लिए किया गया था।

यदि $nपुनरावृत्ति की वांछित संख्या है और आपको इसका पुन: उपयोग नहीं करना है, और आप कुछ कम चाहते हैं:

while ((n--)); do echo -n "$s"; done; echo

nएक चर होना चाहिए - इस तरह से स्थितिगत मापदंडों के साथ काम नहीं करता है। $sपाठ दोहराया जाना है।


2
लूप संस्करणों को करने से दृढ़ता से बचें। printf "%100s" | tr ' ' '='इष्टतम है।
ओदोडो

एक समारोह के रूप में कार्यक्षमता के लिए पैकेजिंग के लिए अच्छी पृष्ठभूमि जानकारी और यश, जो zshसंयोगवश, साथ ही साथ काम करता है । इको-इन-लूप दृष्टिकोण छोटे रिपीट काउंट्स के लिए अच्छी तरह से काम करता है, लेकिन बड़े लोगों के लिए पोसिक्स-कंप्लायंट विकल्प हैं जो उपयोगिताओं पर आधारित हैं , जैसा कि @ Slomojo की टिप्पणी से स्पष्ट है।
mklement0

अपने छोटे लूप के चारों ओर कोष्ठक जोड़ना echos को प्रभावित किए बिना n का मान सुरक्षित रखता है:(while ((n--)); do echo -n "$s"; done; echo)

इको के बजाय प्रिंटफ का उपयोग करें! यह अधिक पोर्टेबल है (इको-एन केवल कुछ सिस्टम पर काम कर सकता है)। देख unix.stackexchange.com/questions/65803/... (स्टीफ़न Chazelas के भयानक जवाब में से एक)
ओलिवर Dulac

@OlivierDulac यहाँ सवाल बैश के बारे में है। कोई फर्क नहीं पड़ता कि आप किस ऑपरेटिंग सिस्टम को चला रहे हैं, अगर आप उस पर बैश का उपयोग कर रहे हैं , तो बैश में एक echoबिलिन है जो समर्थन करता है -n। आप जो कह रहे हैं उसकी भावना बिलकुल सही है। कम से कम गैर-इंटरैक्टिव उपयोग में printfलगभग हमेशा पसंद किया जाना चाहिए echo। लेकिन मुझे नहीं लगता कि यह किसी भी तरह से अनुचित या भ्रामक था, जो किसी echoएक प्रश्न का उत्तर देने के लिए था और जिसने यह जानने के लिए पर्याप्त जानकारी दी कि यह काम करेगा । कृपया यह भी ध्यान दें कि ((n--))(बिना $) के समर्थन के लिए खुद POSIX द्वारा गारंटी नहीं दी जाती है।
एलिया कगन

4

अजगर सर्वव्यापी है और हर जगह समान काम करता है।

python -c "import sys; print('*' * int(sys.argv[1]))" "=" 100

चरित्र और गिनती को अलग-अलग मापदंडों के रूप में पारित किया जाता है।


मुझे लगता है कि यहाँ यही इरादा थाpython -c "import sys; print(sys.argv[1] * int(sys.argv[2]))" "=" 100
gazhay

@loevborg इतना छोटा-सा नहीं है?
नीलमणि

3

बैश 3.0 या उच्चतर में

for i in {1..100};do echo -n =;done

3

एक और मनमाना स्ट्रिंग n बार दोहराने का मतलब है:

पेशेवरों:

  • POSIX शेल के साथ काम करता है।
  • आउटपुट को एक चर को सौंपा जा सकता है।
  • किसी भी स्ट्रिंग को दोहराता है।
  • बहुत तेजी से बहुत बड़े दोहराव के साथ भी।

विपक्ष:

  • Gnu Core Utils की yesकमांड की आवश्यकता है।
#!/usr/bin/sh
to_repeat='='
repeat_count=80
yes "$to_repeat" | tr -d '\n' | head -c "$repeat_count"

ANSI टर्मिनल और US-ASCII वर्णों को दोहराने के लिए। आप एक एएनएसआई सीएसआई एस्केप सीक्वेंस का उपयोग कर सकते हैं। किसी चरित्र को दोहराना सबसे तेज़ तरीका है।

#!/usr/bin/env bash

char='='
repeat_count=80
printf '%c\e[%db' "$char" "$repeat_count"

या वैधानिक रूप से:

80 बार की एक पंक्ति प्रिंट करें =:

printf '=\e[80b\n'

सीमाएं:

  • सभी टर्मिनल repeat_charANSI CSI अनुक्रम को नहीं समझते हैं ।
  • केवल US-ASCII या सिंगल-बाइट ISO वर्ण दोहराए जा सकते हैं।
  • अंतिम कॉलम में बार-बार रुकता है, इसलिए आप टर्मिनल चौड़ाई की परवाह किए बिना एक पूरी लाइन भरने के लिए एक बड़े मूल्य का उपयोग कर सकते हैं।
  • रिपीट केवल प्रदर्शन के लिए है। शेल चर में आउटपुट कैप्चर repeat_charकरना बार-बार वर्ण में ANSI CSI अनुक्रम का विस्तार नहीं करेगा ।

1
मामूली नोट - आरईपी (सीएसआई बी) को सामान्य रूप से चारों ओर लपेटना चाहिए यदि टर्मिनल रैपिंग मोड में है।
jerch

3

यहाँ मैं लिनक्स में स्क्रीन पर वर्णों की एक पंक्ति को प्रिंट करने के लिए उपयोग करता हूं (टर्मिनल / स्क्रीन की चौड़ाई के आधार पर)

स्क्रीन पर "=" प्रिंट करें:

printf '=%.0s' $(seq 1 $(tput cols))

स्पष्टीकरण:

दिए गए अनुक्रम के रूप में कई बार एक समान चिह्न प्रिंट करें:

printf '=%.0s' #sequence

कमांड के आउटपुट का उपयोग करें (यह कमांड सब्सट्रेशन नामक एक बैश फीचर है):

$(example_command)

एक अनुक्रम दें, मैंने उदाहरण के रूप में 1 से 20 का उपयोग किया है। अंतिम कमांड में 20 के बजाय tput कमांड का उपयोग किया जाता है:

seq 1 20

वर्तमान में टर्मिनल में उपयोग किए जाने वाले स्तंभों की संख्या दें:

tput cols


2
repeat() {
    # $1=number of patterns to repeat
    # $2=pattern
    printf -v "TEMP" '%*s' "$1"
    echo ${TEMP// /$2}
}


2

प्रस्तावित अजगर समाधान का एक और अधिक सुंदर विकल्प हो सकता है:

python -c 'print "="*(1000)'

1

उस स्थिति में, जब आप किसी वर्ण को दोहराना चाहते हैं, तो यह कहते हुए कि आपके द्वारा की जा सकने वाली स्ट्रिंग की लंबाई:

#!/bin/bash
vari='AB'
n=$(expr 10 - length $vari)
echo 'vari equals.............................: '$vari
echo 'Up to 10 positions I must fill with.....: '$n' equal signs'
echo $vari$(perl -E 'say "=" x '$n)

यह प्रदर्शित करता है:

vari equals.............................: AB  
Up to 10 positions I must fill with.....: 8 equal signs  
AB========  

lengthसाथ काम नहीं करेगा expr, आप शायद मतलब था n=$(expr 10 - ${#vari}); हालांकि, यह बाश के अंकगणितीय विस्तार का उपयोग करने के लिए सरल और अधिक कुशल है n=$(( 10 - ${#vari} )):। इसके अलावा, आपके उत्तर के मूल में बहुत पर्ल दृष्टिकोण है जो ओपी को बैश विकल्प की तलाश में है।
mklement0

1

यह एलिया कगन की जासूसी का लंबा संस्करण है:

while [ $(( i-- )) -gt 0 ]; do echo -n "  "; done

बेशक आप उस के लिए भी प्रिंटफ का उपयोग कर सकते हैं, लेकिन वास्तव में मेरी पसंद के अनुसार नहीं:

printf "%$(( i*2 ))s"

यह संस्करण डैश संगत है:

until [ $(( i=i-1 )) -lt 0 ]; do echo -n "  "; done

मैं प्रारंभिक संख्या होने के साथ।


बैश में और एक सकारात्मक n के साथ: while (( i-- )); do echo -n " "; doneकाम करता है।

1
function repeatString()
{
    local -r string="${1}"
    local -r numberToRepeat="${2}"

    if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]]
    then
        local -r result="$(printf "%${numberToRepeat}s")"
        echo -e "${result// /${string}}"
    fi
}

नमूना चलता है

$ repeatString 'a1' 10 
a1a1a1a1a1a1a1a1a1a1

$ repeatString 'a1' 0 

$ repeatString '' 10 

संदर्भ लिब पर: https://github.com/gdbtek/linux-cookbooks/blob/master/lbooks/util.bash


1

मैं इसे प्रतिध्वनि के साथ कैसे कर सकता था?

आप इसके साथ कर सकते हैं echoयदि echoइसके बाद है sed:

echo | sed -r ':a s/^(.*)$/=\1/; /^={100}$/q; ba'

दरअसल, यह echoवहां अनावश्यक है।


1

मेरा उत्तर थोड़ा अधिक जटिल है, और शायद एकदम सही नहीं है, लेकिन बड़ी संख्या में आउटपुट की तलाश करने वालों के लिए, मैं 3 सेकंड में लगभग 10 मिलियन करने में सक्षम था।

repeatString(){
    # argument 1: The string to print
    # argument 2: The number of times to print
    stringToPrint=$1
    length=$2

    # Find the largest integer value of x in 2^x=(number of times to repeat) using logarithms
    power=`echo "l(${length})/l(2)" | bc -l`
    power=`echo "scale=0; ${power}/1" | bc`

    # Get the difference between the length and 2^x
    diff=`echo "${length} - 2^${power}" | bc`

    # Double the string length to the power of x
    for i in `seq "${power}"`; do 
        stringToPrint="${stringToPrint}${stringToPrint}"
    done

    #Since we know that the string is now at least bigger than half the total, grab however many more we need and add it to the string.
    stringToPrint="${stringToPrint}${stringToPrint:0:${diff}}"
    echo ${stringToPrint}
}

1

सरलतम इस एक-लाइनर को बैश में उपयोग करना है:

seq 10 | xargs -n 1 | xargs -I {} echo -n  ===\>;echo


1

एक अन्य विकल्प GNU seq का उपयोग करना है और इसके द्वारा उत्पन्न सभी संख्याओं और नई संख्याओं को हटाना है:

seq -f'#%.0f' 100 | tr -d '\n0123456789'

यह कमांड #वर्ण को 100 बार प्रिंट करता है ।


1

अधिकांश मौजूदा समाधान सभी {1..10}शेल के सिंटैक्स समर्थन पर निर्भर करते हैं , जो कि bash- और zsh- विशिष्ट है, और tcshओपनबीएसडी kshऔर अधिकांश गैर-बैश में काम नहीं करता है sh

निम्नलिखित किसी भी शेल में ओएस एक्स और सभी * बीएसडी सिस्टम पर काम करना चाहिए; वास्तव में, इसका उपयोग विभिन्न प्रकार के सजावटी अंतरिक्ष की एक पूरी मैट्रिक्स उत्पन्न करने के लिए किया जा सकता है:

$ printf '=%.0s' `jot 64` | fold -16
================
================
================
================$ 

अफसोस की बात है, हम एक अनुगामी newline नहीं मिलता है; जो printf '\n'गुना के बाद एक अतिरिक्त द्वारा तय किया जा सकता है :

$ printf "=%.0s" `jot 64` | fold -16 ; printf "\n"
================
================
================
================
$ 

संदर्भ:


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