我怎样才能在Bash中重复一个角色?

时间:2011-03-18 08:45:42

标签: bash shell echo

我如何使用echo

执行此操作
perl -E 'say "=" x 100'

34 个答案:

答案 0 :(得分:326)

您可以使用:

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

这是如何运作的:

Bash扩展{1..100},命令变为:

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

我已经将printf的格式设置为=%.0s,这意味着无论给出什么参数,它都将始终打印一个=。因此它会打印100 = s。

答案 1 :(得分:79)

没有简单的方法。但是例如:

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

或许是符合标准的方式:

printf %100s |tr " " "="

还有一个tput rep,但对于我手边的终端(xterm和linux),它们似乎不支持它:)

答案 2 :(得分:39)

有多种方法可以做到这一点。

使用循环:

  • 支撑扩展可以与整数文字一起使用:

    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次。

使用headprintf等)和tr

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

答案 3 :(得分:38)

向@ gniourf_gniourf提示他的输入。

注意:此答案回答原始问题,但 通过比较效果补充现有的有用答案。< /强>

只在执行速度方面比较 - 内存要求被考虑在内(它们在各种解决方案中各不相同,并且可能与大量重复计数有关)。

<强>要点:

  • 如果重复计数 ,比如说高达100左右,值得使用 Bash-only解决方案< / em> ,因为外部实用程序的启动成本很重要,尤其是Perl。
    • 但实际上,如果你只需要一个重复字符的实例,那么所有现有的解决方案都可以。
  • 重复计数使用外部实用程序 ,因为它们会更快。
    • 特别是,避免使用大字符串替换Bash的全局子字符串 (例如,${var// /=}),因为它非常慢。

以下是2012年末iMac采用3.2 GHz Intel Core i5 CPU和Fusion Drive的时序,运行OSX 10.10.4和bash 3.2.57,平均值为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
  • 仅限Bash的解决方案领先一揽子计划 - 但只有重复计数这么小! (见下文)。
  • 外部实用程序的启动成本在这里很重要,尤其是Perl。如果必须在循环中调用它 - 在每次迭代中使用重复计数 - 请避免使用多实用程序awkperl解决方案。
  • 大重复次数:1000000(100万)
[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
  • 问题的Perl解决方案是迄今为止最快的。
  • Bash的全局字符串替换(${foo// /=})在使用大字符串时令人费解地极其缓慢,并且已经被淘汰(在Bash 4.3.30中花了大约50分钟(!),并且在Bash 3.2.57中更长 - 我从不等待它完成。)
  • Bash循环很慢,算术循环((( i= 0; ... )))比大括号扩展({1..n})慢 - 尽管算术循环的内存效率更高。
  • awk指的是 BSD awk(也可以在OSX上找到) - 它明显慢于gawk(GNU Awk),特别是mawk
  • 请注意,大计数和多字符。字符串,内存消耗可以成为一个考虑因素 - 这方面的方法不同。

以下是产生上述内容的 Bash脚本testrepeat)。 这需要2个参数:

  • 字符重复计数
  • 可选地,执行和计算平均时间的测试运行次数

换句话说:上述时间是通过testrepeat 100 1000testrepeat 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

答案 4 :(得分:28)

我刚刚使用seq找到了一种非常简单的方法:

更新:这适用于OS X附带的BSD seq。带有其他版本的YMMV

seq  -f "#" -s '' 10

将打印&#39;#&#39; 10次​​,像这样:

##########
  • -f "#"设置格式字符串以忽略这些数字,并为每个数字打印#
  • -s ''将分隔符设置为空字符串,以删除seq在每个数字之间插入的换行符
  • -f-s之后的空格似乎很重要。

编辑:这是一个方便的功能......

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

你可以这样打电话......

repeat "#" 10

注意:如果您重复#,那么引号很重要!

答案 5 :(得分:17)

以下是两种有趣的方式:

ubuntu@ubuntu:~$ yes = | head -10 | paste -s -d '' -
==========
ubuntu@ubuntu:~$ yes = | head -10 | tr -d "\n"
==========ubuntu@ubuntu:~$ 

请注意,这两者略有不同 - paste方法以新行结尾。 tr方法没有。

答案 6 :(得分:11)

没有简单的方法。使用printf和替换来避免循环。

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

答案 7 :(得分:7)

这是我用来在linux屏幕上打印一行字符的方法(基于终端/屏幕宽度)

在屏幕上打印“ =“:

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

说明:

按照给定的顺序打印等号多次:

printf '=%.0s' #sequence

使用命令的输出(这是一种称为Command Substitution的bash功能):

$(example_command)

给出一个序列,我以1到20为例。在最后一个命令中,使用tput命令而不是20:

seq 1 20

给出终端当前使用的列数:

tput cols

答案 8 :(得分:7)

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

或者

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

Example

答案 9 :(得分:5)

如果您希望echoprintf的不同实施和/或bash以外的其他实施符合POSIX兼容性和一致性:

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'相同的输出。

答案 10 :(得分:4)

我想问题的最初目的是使用shell的内置命令来完成这个任务。因此for循环和printf s是合法的,而repperl以及jot则不合法。仍然是以下命令

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

例如,

打印一个窗口范围的\/\/\/\/\/\/\/\/\/\/\/\/

答案 11 :(得分:4)

正如其他人所说,在bash brace expansion之前parameter expansion,所以{m,n}范围只能包含文字。 seqjot提供了干净的解决方案,但即使您在每个系统上使用相同的shell,也无法从一个系统完全移植到另一个系统。 (虽然seq越来越多可用;例如,in FreeBSD 9.3 and higher。)eval和其他形式的间接总是有效,但有点不优雅。

幸运的是,bash supports C-style for loops(仅限算术表达式)。所以这里是一个简洁的纯粹的bash&#34;方式:

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

这将重复次数作为第一个参数,将重复的字符串(可能是单个字符,如问题描述中)作为第二个参数。 repecho 7 b输出bbbbbbb(以换行符结尾)。

Dennis Williamsonessentially this solution four years ago in his excellent answer提交给Creating string of repeated characters in shell script。我的函数体与那里的代码略有不同:

  • 由于此处的重点是重复单个字符而shell是bash,因此使用echo代替printf可能是安全的。我在这个问题中阅读了问题描述,表达了使用echo进行打印的偏好。上面的函数定义适用于bash和ksh93。虽然printf更具可移植性(并且通常应该用于此类事情),但echo的语法可以说更具可读性。

    有些贝壳&#39; echo内置函数将-本身解释为一个选项 - 即使使用stdin作为输入的-的通常含义,对echo也没有意义。 zsh这样做。肯定存在echo,不能识别-nit is not standard。 (许多Bourne风格的贝壳根本不接受C风格的循环,因此不需要考虑他们的echo行为。)

  • 这里的任务是打印序列; there,是将其分配给变量。

如果$n是所需的重复次数而您不必重复使用,并且您想要更短的内容:

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

n必须是变量 - 这种方式不适用于位置参数。 $s是要重复的文字。

答案 12 :(得分:3)

纯粹的Bash方式,没有eval,没有子shell,没有外部工具,没有大括号扩展(即,你可以在变量中重复这个数字):

如果您获得的变量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 varnameprintf不是打印到标准输出,而是将格式化字符串的内容放在变量varname中。
  • &#39;%* s&#39;:printf将使用该参数打印相应数量的空格。例如,printf '%*s' 42将打印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}"
}

答案 13 :(得分:2)

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

答案 14 :(得分:2)

问题在于如何使用echo

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

这将与perl -E 'say "=" x 100'完全相同,但仅使用echo

答案 15 :(得分:2)

Python无处不在,无处不在。

TeachersData[TeachersData$Teacher_ID==input$Selecter,]

字符和计数作为单独的参数传递。

答案 16 :(得分:2)

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

答案 17 :(得分:2)

在bash 3.0或更高版本中

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

答案 18 :(得分:1)

这是Eliah Kagan所支持的更长版本:

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

当然你也可以使用printf,但不是我真的喜欢:

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

此版本兼容Dash:

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

以i为初始数字。

答案 19 :(得分:1)

如果你想重复一个字符n次是一个VARIABLE次数,这取决于你可以做的字符串的长度:

#!/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========  

答案 20 :(得分:1)

  

我该如何用echo做到这一点?

可以用做echo,如果echo后跟sed

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

实际上,在那里echo是不必要的。

答案 21 :(得分:1)

不要堆积,而是另一种纯Bash方法利用数组的${//}替换:

$ arr=({1..100})
$ printf '%s' "${arr[@]/*/=}"
====================================================================================================

答案 22 :(得分:0)

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

双破折号 -- 表示“命令行结束标志”,所以不要试图解析命令行选项之后的内容。

如果您想多次打印破折号 - 字符而不是 = 字符并且不包括双破折号 -- 这就是您将得到的:

$ printf '-%.0s' {1..100}
bash: printf: -%: invalid option
printf: usage: printf [-v var] format [arguments]

为什么不创建一个这样的单行函数:

function repeat() { num="${2:-100}"; printf -- "$1%.0s" $(seq 1 $num); }

然后,你可以这样称呼它:

$ repeat -
----------------------------------------------------------------------------------------------------

或者像这样:

$ repeat =
====================================================================================================

或者像这样:

$ repeat '*' 8
********

答案 23 :(得分:0)

版本稍长,但是如果由于某些原因必须使用纯Bash,则可以使用带有递增变量的while循环:

length[j]

答案 24 :(得分:0)

我的提案(接受n的变量值)

~4.5.0

答案 25 :(得分:0)

另一个意思是将任意字符串重复n次:

优点:

  • 使用POSIX shell。
  • 可以将输出分配给变量。
  • 重复任何字符串。
  • 即使重复次数很大,也非常快。

缺点:

  • 需要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字符。您可以使用ANSI CSI转义序列。这是重复字符的最快方法。

#!/usr/bin/env bash

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

或静态地:

打印80行=

printf '=\e[80b\n'

限制:

  • 并非所有终端都能理解repeat_char ANSI CSI序列。
  • 只能重复使用US-ASCII或单字节ISO字符。
  • 重复在最后一列停止,因此无论终端宽度如何,您都可以使用较大的值来填充整行。
  • 重复仅用于显示。将输出捕获到shell变量中不会将repeat_char ANSI CSI序列扩展为重复的字符。

答案 26 :(得分:0)

大多数现有解决方案都依赖于{1..10}bash特定的Shell语法支持,并且不适用于zsh或OpenBSD的ksh和大多数非流行tcsh

以下内容应在OS X和任何外壳中的所有* BSD系统上运行;实际上,它可以用于生成各种类型的装饰空间的整个矩阵:

sh

遗憾的是,我们没有尾随换行符;折叠后可以通过额外的$ printf '=%.0s' `jot 64` | fold -16 ================ ================ ================ ================$ 进行固定:

printf '\n'

参考文献:

答案 27 :(得分:0)

另一种选择是使用GNU seq并删除其生成的所有数字和换行符:

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

此命令将#字符打印​​100次。

答案 28 :(得分:0)

一个比拟议的Python解决方案更优雅的替代方案可能是:

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

答案 29 :(得分:0)

最简单的方法是在bash中使用这种单线:

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

答案 30 :(得分:0)

我的回答比较复杂,可能还不完美,但是对于那些希望输出大量数字的人来说,我能够在3秒钟内完成约一千万次操作。

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}
}

答案 31 :(得分:0)

最简单的方法是在csh / tcsh中使用这种单行代码:

printf "%50s\n" '' | tr '[:blank:]' '[=]'

答案 32 :(得分:0)

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/libraries/util.bash

答案 33 :(得分:-1)

n=5; chr='x'; chr_string='';
for (( i=0; $i<$n; i++ ))
do
    chr_string=$chr_string$chr
done
echo -n "$chr_string"

适用于...
n =整数(包括零和整数)。
chr =可打印的空白(空格和制表符)。