在bash中重复打印一个角色

Ank*_*wal 48 bash shell

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

print('%' * 3)
Run Code Online (Sandbox Code Playgroud)

%%%
Run Code Online (Sandbox Code Playgroud)

Caf*_*eur 129

实际上有一个可以做到这一点的单线程:

    printf "%0.s-" {1..10}
Run Code Online (Sandbox Code Playgroud)

版画

    ----------
Run Code Online (Sandbox Code Playgroud)

这是传递给的参数的细分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)
Run Code Online (Sandbox Code Playgroud)

这将相反传递参数"1 2 3 4 ... $ variable" printf,精确打印$variable" - "的实例

  • 非常好,但这不适用于***#!/ bin/sh***,但仅适用于***#!/ bin/bash*** (5认同)
  • 由于这使用内置的bash,对于少量重复的字符,它应比生成外部进程的方法更快。对于较大的数字,`printf'%* s'1000000''| tr'''-'`和其他方法更快。 (2认同)
  • 遇到这个问题 - 以及许多其他类似问题 - 因为我需要在密码破解程序中创建一个包含1,000,000个单词的词表,以进行性能测试. (2认同)

gho*_*g74 41

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

$ s=$(printf "%-30s" "*")
$ echo "${s// /*}"
******************************
Run Code Online (Sandbox Code Playgroud)

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

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

测试运行:

$ printf_new "*" 20
********************
$ printf_new "*" 10
**********
$ printf_new "%" 10
%%%%%%%%%%
Run Code Online (Sandbox Code Playgroud)

  • 如果你使用`printf -v`,你可以避免使用子shell.`printf -v str'%-30s'''; echo"$ {str ///*}"` (2认同)
  • -1。这非常慢,尤其是对于> 1000个字符。几乎所有东西都更快,包括`printf'%.s *'{1..30}`,或`printf'%* s'1000000''| tr''*'`。 (2认同)
  • printf_new在第三次测试运行时失败.我会这样解决:`printf -vv"% - *s""$ num"""; echo"$ {v ///$ str}"` (2认同)
  • 在bash中实现这些微不足道的事情让我哭泣. (2认同)

Dea*_*ode 21

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

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

perl -E "print '*' x 1000"
Run Code Online (Sandbox Code Playgroud)

排在第二位的是python命令:

python -c "print('*' * 1000)"
Run Code Online (Sandbox Code Playgroud)

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

head -c 1000 /dev/zero | tr '\0' '*'
Run Code Online (Sandbox Code Playgroud)

第四位是使用printf内置bash的那个tr:

printf '%*s' 1000 | tr ' ' '*'
Run Code Online (Sandbox Code Playgroud)

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

printf '%.s*' {1..1000}
Run Code Online (Sandbox Code Playgroud)


man*_*lds 10

我喜欢这个:

echo $(yes % | head -n3)
Run Code Online (Sandbox Code Playgroud)

你可能不喜欢这个:

for ((i=0; i<3; i++)){
   echo -ne "%"
}
Run Code Online (Sandbox Code Playgroud)

你可能会喜欢这个:

s=$( printf "%3s" ); echo " ${s// /%}"
Run Code Online (Sandbox Code Playgroud)

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

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

echo %{,,}
Run Code Online (Sandbox Code Playgroud)

  • +1是'yes`和`head`的组合 (7认同)

Gre*_*ill 5

这很丑陋,但你可以这样做:

$ for a in `seq 5`; do echo -n %; done
%%%%%
Run Code Online (Sandbox Code Playgroud)

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

  • @Deadcode -1 通常保留用于不正确的答案,而不是低效的答案。可能还有其他方法可以完成此操作,但是这是一种完全有效的方法...... (5认同)
  • 当您可以简单地编写:`for a in {1..5}; 时,为什么要使用另一个程序?执行 echo -n %; 完成`。) (2认同)