在bash中重复打印一个角色

时间:2011-04-27 04:20:56

标签: bash shell

有没有办法在bash中重复打印相同的字符,就像你可以使用这个结构在python中这样做:

print('%' * 3)

给出

%%%

9 个答案:

答案 0 :(得分:114)

实际上有一个单行可以做到这一点:

    printf "%0.s-" {1..10}

打印

    ----------

以下是传递给printf的参数的细分:

  • %s - 指定任意长度的字符串
  • %0s - 这指定一个零长度的字符串,但如果参数较长,则会打印整个内容
  • %0.s - 这与上面相同,但句点告诉printf如果字符串超过指定长度(即零),则截断字符串
  • {1..10} - 这是一个大括号扩展,实际上传递参数“1 2 3 4 5 6 7 8 9 10”
  • “ -​​ ” - 这是为printf提供的额外字符,它可以是任何内容(对于“%”,您必须先用另一个“%”转义它,即“%%”)
  • 最后,printf的默认行为如果给它提供的参数多于格式字符串中指定的参数,则循环回格式字符串的开头并再次运行。

这里发生的最终结果就是你告诉printf如果提供的字符串长于零,你希望它打印一个没有多余字符的零长度字符串。然后在此零长度字符串后打印“ - ”(或任何其他字符集)。然后你提供10个参数,所以它打印10个零长度字符串,每个字符串后跟一个“ - ”。

这是一个单行程,可以打印任意数量的重复字符!

编辑:

巧合的是,如果您想要打印$variable个字符,您只需稍微更改参数以使用seq而不是按如下方式进行扩展:

    printf '%0.s-' $(seq 1 $variable)

这会将参数“1 2 3 4 ... $ variable”传递给printf,精确打印{ - 1}}个实例“ - ”

答案 1 :(得分:38)

当然,只需使用printf和一些bash字符串操作

$ s=$(printf "%-30s" "*")
$ echo "${s// /*}"
******************************

应该有一个更短的方式,但目前我就是这样做的。您可以将其转换为可以存储在库中以供将来使用的函数

printf_new() {
 str=$1
 num=$2
 v=$(printf "%-${num}s" "$str")
 echo "${v// /*}"
}

试运行:

$ printf_new "*" 20
********************
$ printf_new "*" 10
**********
$ printf_new "%" 10
%%%%%%%%%%

答案 2 :(得分:18)

此问题的当前接受答案(ghostdog74)提供了一种方法,即使是适度大量的字符也会执行得非常慢。最高投票的答案(CaffeineConnoisseur)更好,但仍然很慢。

在我的测试中,这是最快的执行(甚至比python版本更快):

perl -E "print '*' x 1000"

排在第二位的是python命令:

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

如果perl和python都不可用,那么这是第三好的:

head -c 1000 /dev/zero | tr '\0' '*'

排在第四位的是使用bash printf内置tr的人:

printf '%*s' 1000 | tr ' ' '*'

这里有一个(来自CaffeineConnoisseur的答案),对于大量重复的字符来说速度排在第五位,但对于小数字来说可能更快(因为只使用了内置的bash,而不是产生外部过程):

printf '%.s*' {1..1000}

答案 3 :(得分:9)

我喜欢这个:

echo $(yes % | head -n3)

你可能不喜欢这个:

for ((i=0; i<3; i++)){
   echo -ne "%"
}

你可能会喜欢这个:

s=$( printf "%3s" ); echo " ${s// /%}"

来源:http://dbaspot.com/shell/357767-bash-fast-way-repeat-string.html

还有这种形式,但不是很有用:

echo %{,,}

答案 4 :(得分:3)

这很难看,但你可以这样做:

$ for a in `seq 5`; do echo -n %; done
%%%%%

当然,seq是一个外部程序(你可能有)。

答案 5 :(得分:1)

另一个:

char='%'
count=5
result=$( printf "%${count}s" ' ' )
echo -e ${result// /$char}

答案 6 :(得分:1)

  1. 可以从\0获取任意数量的零(/dev/zero)字符。唯一要做的就是

    head -c 20 /dev/zero |tr '\0' '+'
    

    请注意,headtr是外部命令。这样就可以在单独的过程中调用它。

  2. 可以使用字符串缓存“优化”此解决方案。

    CACHE="$(head -c 1000 /dev/zero |tr '\0' '+')"
    echo "${CACHE:0:10}"
    echo "${CACHE:0:100}"
    echo "${CACHE:0:300}"
    

    echo语句中只有bash个内置函数。所以,我们可以在循环中使用它。

答案 7 :(得分:0)

这是最简单的方法

seq -s % 4|tr -d '[:digit:]'

请注意,创建的序列中只有3'%'。

答案 8 :(得分:0)

#!/usr/bin/awk -f
BEGIN {
  while (c++ < 3) printf "%"
}

结果

%%%