如何在 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
在一般情况下,如果你能想出一个生成器表达式(至少)产生所需的重复次数,你就可以循环它。这是 seq
和 jot
的简单替换:
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)
##############################
我想重复#
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
在一般情况下,如果你能想出一个生成器表达式(至少)产生所需的重复次数,你就可以循环它。这是 seq
和 jot
的简单替换:
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)
##############################