2011-04-27 48 views
31

反复打印字符是有没有办法在bash反复打印相同的字符,就像你可以使用此结构来做到这一点在Python:在bash

print('%' * 3) 

%%% 

回答

29

肯定的是,只要使用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

如果你使用'printf -v',你可以在这里避免subshel​​l。 'printf -v str'%-30s'''; echo“$ {str ///*}”' – kojiro 2012-06-20 15:20:34

+1

-1。这非常慢,特别是对于> 1000个字符。几乎所有东西都比较快,包括'printf'%.s *'{1..30}'或'printf'%* s'1000000''| tr'''*''大数字。 – Deadcode 2014-02-26 17:17:27

+1

第三次测试运行时,printf_new失败。我会像这样修复它:'printf -v v“% - * s”“$ num”“”; echo“$ {v ///$ str}”' – jarno 2015-08-28 21:22:19

2

这是丑陋,但你可以做这样的:

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

当然,seq是外部亲克(你可能有)。

+2

为什么使用另一个程序时,你可以简单地写:'for a in {1..5};做echo -n%;完成'。) – 2013-10-02 09:06:24

+1

我想我的自我,在一个脚本中,我的“解决方案”不起作用,这是您的解决方案。 – 2013-10-02 09:21:35

+0

-1。比'printf'%0.s %%“{1..5}'慢,这反过来慢于'printf'%* s'5''| tr'''%''。 – Deadcode 2014-02-26 17:08:07

7

我喜欢这样的:

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 %{,,} 
+5

+1是'yes'和'head'的组合 – fmark 2011-05-01 02:28:00

+0

这就是现在人们使用的!我去寻找'/ dev/y',并且无法在我的现​​代系统上找到它。 – 2013-05-17 22:05:03

0

还有一句:

char='%' 
count=5 
result=$(printf "%${count}s" ' ') 
echo -e ${result// /$char} 
1
  1. 有可能从/dev/zero获取任意数量的零(\0)字符。剩下要做的唯一事情就是

    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内置函数。所以,我们可以循环使用它。

+1

这不起作用;它会进入一个无限循环,输出不限数量的字符,而不是像预期的那样。正确的命令是'head -c 20/dev/zero | tr'\ 0''+''。 – Deadcode 2014-02-26 16:43:20

+0

这似乎是ssvda的一个错字。它应该是'head -c 20'来打印前20个字符。 'head -n 20'显示前20行。 – Six 2015-03-02 17:30:00

89

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

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

打印

---------- 

这里传递给printf参数的故障:

  • % s - 这指定了任何长度的字符串
  • %0 - 这指定零长度的字符串,但如果参数是时间越长,将打印整个事情
  • %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,精确打印$variable” - “的实例

+4

非常好,但是这在***#!/ bin/sh ***中不起作用,但是只在***#!/ bin/bash *** – 2013-10-02 09:00:28

+0

因为这使用了内置的bash,所以对于少量的重复的字符应该比生成外部进程的方法更快。对于大数字,'printf'%* s'1000000''| tr'''-''和其他方法更快。 – Deadcode 2014-02-26 17:13:14

+0

我唯一的问题是,你想在什么情况下打印重复字符100万次?我可以看到的其他操作,但这只会让您看起来毫无意义的字符饱和。 – CaffeineConnoisseur 2014-02-27 19:09:16

-1

以下是最简单的方法:

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

注意在创建的序列中只有3个'%'。

+0

-1。打印一个主要的换行符,打印比传递的数字少一个字符,并且比'printf'%* s'3''| tr'''%''慢。 – Deadcode 2014-02-26 17:01:24

15

这个问题目前接受的答案(由ghostdog74提供)提供了一种即使是中等数量的字符也执行得非常缓慢的方法。最高票数的答案(CaffeineConnoisseur)较好,但仍然很慢。

这里是什么,在我的测试中,已执行速度最快的是(甚至快于Python版本):

perl -E "print '*' x 1000" 

在第二位的是python命令:

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

如果没有perl也不是蟒蛇可用,那么这是第三好的:

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

而在第四位是一个你唱的bash printf内置有tr一起:

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

而且这里有一个(从CaffeineConnoisseur的回答)这是在速度,大量重复的字符的第五位,但可能是小数目更快(由于仅使用内置在bash,而不是产卵一个外部进程):

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

假设'*'是输出的字符,最后一个例子中前面的'%.s'的目的是什么? – Hashim 2017-02-12 23:02:51

+0

“%s”是printf的格式规范,简称含义字符串。在“%”和“s”之间,您可以设置字符串的长度属性。使用“。”或“.0”将最大字符串长度设置为零,不打印该字符串。在此示例中,范围扩展为1 2 3 4 5 ..... 98 99 100,每个数字被视为零长度字符串。这是如何控制打印的星号的数量。 – 2017-09-20 04:34:29

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

结果

 
%%%