如何在 Bourne Shell 中重复一个字符?

How to repeat a character in Bourne Shell?

我想重复# 10 次,例如:

"##########" 

我怎样才能在 Bourne shell (/bin/sh) 中做到这一点?我试过使用 print 但我猜它只适用于 bash shell.

请不要给出 bash 语法。

这会打印出 ##########:

for a in `seq 10`; do echo -n "#"; done

shell 本身没有明显的重复字符串的功能。仅仅十次重复,就很难击败显而易见的

echo '##########'

为了将单个字符重复指定的次数,即使在繁忙的 BusyBox 上也应该可以工作。

dd if=/dev/zero bs=10 count=1 | tr '[=11=]' '#'

不是很优雅但开销相当低。 (您可能需要从 dd 重定向标准错误以摆脱讨厌的进度消息。)

如果您有一个保证足够长的文件(例如,您当前的脚本 运行),您可以将前 10 个字符替换为 tr

head -c 10 "[=12=]" | tr '[=12=]0-7' '#'

如果你有一个真正传统的用户空间(例如 head 不支持 -c 选项)一个 1980 年代兼容的变体可能是

yes '#' | head -n 10 | tr -d '\n'

(您的 tr 可能不完全支持我在此处使用的反斜杠序列。请参阅其手册页或 1970 年代后期的当地学术程序员。)

... 或者,哎呀

strings /bin/sh | sed 's/.*/#/;10q' | tr -d '\n'  # don't do this at home :-)

在没有外部实用程序的纯遗留 Bourne shell 中,你真的不能比

做得更好
for f in 0 1 2 3 4 5 6 7 8 9; do
    printf '#'
done

在一般情况下,如果你能想出一个生成器表达式(至少)产生所需的重复次数,你就可以循环它。这是 seqjot 的简单替换:

echo | awk '{ for (i=0; i<10; ++i) print i }'

但是你也可以做 Awk 的输出:

echo | awk '{ for (i=0; i<10; ++i) printf "#" }'

好吧,没有管道和分叉的纯 Bourne Shell (POSIX) 解决方案可能是

i=0; while test $i -lt 10; do printf '#'; : $((++i)); done; printf '\n'

这很容易推广到其他重复的字符串,例如shell 函数

rept () {
  i=0
  while test $i -lt ; do
    printf '%s' ""
    : $((++i))
  done
  printf '\n'
}
rept 10 '#'

如果 HP Bourne Shell 不完全 POSIX 并且不支持 : $(()) 的算术替换,您可以使用 i=$(expr $i + 1) 代替。

您可以将此技巧与 printf 一起使用:

$ printf "%0.s#" {1..10}
##########

如果数字可以是一个变量,那么你需要使用seq:

$ var=30
$ printf "%0.s#" $(seq $var)
##############################