我该怎么办echo
?
perl -E 'say "=" x 100'
ruby -e 'puts "=" * 100'
或python -c 'print "=" * 100'
printf
同seq
)svrb=`printf '%.sv' $(seq $vrb)`
我该怎么办echo
?
perl -E 'say "=" x 100'
ruby -e 'puts "=" * 100'
或python -c 'print "=" * 100'
printf
同seq
)svrb=`printf '%.sv' $(seq $vrb)`
Answers:
您可以使用:
printf '=%.0s' {1..100}
工作原理:
Bash展开{1..100},因此命令变为:
printf '=%.0s' 1 2 3 4 ... 100
我已经设置了printf的格式,=%.0s
这意味着=
无论给定什么参数,它都将始终打印单个。因此它打印100 =
秒。
repl = 100
(eval
不幸的是,为了使括号扩展基于变量repl() { printf "$1"'%.s' $(eval "echo {1.."$(($2))"}"); }
seq
代替例如$(seq 1 $limit)
。
$s%.0s
,%.0s$s
否则破折号会导致printf
错误。
printf
:它将继续应用格式字符串,直到没有剩余参数为止。我以为它只处理一次格式字符串!
没有简单的方法。但例如:
seq -s= 100|tr -d '[:digit:]'
或者也许是符合标准的方式:
printf %100s |tr " " "="
还有一个tput rep
,但是至于我的终端(xterm和linux)他们似乎不支持它:)
=
字符。
printf
tr
是唯一的POSIX解决方案,因为seq
,yes
而{1..3}
不是POSIX。
printf %100s | sed 's/ /abc/g'
-输出'abcabcabc ...'–
tr
)。您也可以将其扩展为printf "%${COLUMNS}s\n" | tr " " "="
。
wc
。我唯一可以得出的结论是“ seq
不应该使用”。
向@ gniourf_gniourf表示感谢。
注意:此答案未回答原始问题,但补充由现有的,有用的答案比较性能。
解决方案是 在执行速度方面比较 - 不考虑内存需求(它们在解决方案中会有所不同,并且可能与大重复次数有关)。
摘要:
${var// /=}
),因为这太慢了。以下是 时机了3.2 GHz的英特尔酷睿i5 CPU和融合驱动器,运行OSX 10.10.4和bash 3.2.57在后期2012的iMac采取,并且是平均1000个奔跑。
条目是:
M
...潜在的多重字符解决方案S
...一个单只字符数限制的解决方案P
...符合POSIX的解决方案[M, P] printf %.s= [dogbane]: 0.0002
[M ] printf + bash global substr. replacement [Tim]: 0.0005
[M ] echo -n - brace expansion loop [eugene y]: 0.0007
[M ] echo -n - arithmetic loop [Eliah Kagan]: 0.0013
[M ] seq -f [Sam Salisbury]: 0.0016
[M ] jot -b [Stefan Ludwig]: 0.0016
[M ] awk - $(count+1)="=" [Steven Penny (variant)]: 0.0019
[M, P] awk - while loop [Steven Penny]: 0.0019
[S ] printf + tr [user332325]: 0.0021
[S ] head + tr [eugene y]: 0.0021
[S, P] dd + tr [mklement0]: 0.0021
[M ] printf + sed [user332325 (comment)]: 0.0021
[M ] mawk - $(count+1)="=" [Steven Penny (variant)]: 0.0025
[M, P] mawk - while loop [Steven Penny]: 0.0026
[M ] gawk - $(count+1)="=" [Steven Penny (variant)]: 0.0028
[M, P] gawk - while loop [Steven Penny]: 0.0028
[M ] yes + head + tr [Digital Trauma]: 0.0029
[M ] Perl [sid_com]: 0.0059
awk
,和perl
解决方案。[M ] Perl [sid_com]: 0.0067
[M ] mawk - $(count+1)="=" [Steven Penny (variant)]: 0.0254
[M ] gawk - $(count+1)="=" [Steven Penny (variant)]: 0.0599
[S ] head + tr [eugene y]: 0.1143
[S, P] dd + tr [mklement0]: 0.1144
[S ] printf + tr [user332325]: 0.1164
[M, P] mawk - while loop [Steven Penny]: 0.1434
[M ] seq -f [Sam Salisbury]: 0.1452
[M ] jot -b [Stefan Ludwig]: 0.1690
[M ] printf + sed [user332325 (comment)]: 0.1735
[M ] yes + head + tr [Digital Trauma]: 0.1883
[M, P] gawk - while loop [Steven Penny]: 0.2493
[M ] awk - $(count+1)="=" [Steven Penny (variant)]: 0.2614
[M, P] awk - while loop [Steven Penny]: 0.3211
[M, P] printf %.s= [dogbane]: 2.4565
[M ] echo -n - brace expansion loop [eugene y]: 7.5877
[M ] echo -n - arithmetic loop [Eliah Kagan]: 13.5426
[M ] printf + bash global substr. replacement [Tim]: n/a
${foo// /=}
)在使用大字符串时令人费解地缓慢,并且已经退出运行(在Bash 4.3.30中花费了大约50分钟(!),在Bash 3.2.57中甚至更长的时间-我从未等待完成)。(( i= 0; ... ))
)比括号扩展的({1..n}
) -尽管算术循环的内存效率更高。awk
指的是BSD awk
(也可以在OSX上找到)-明显比gawk
(GNU Awk)慢,尤其是mawk
。这是产生以上内容的Bash脚本(testrepeat
)。它有两个参数:
换句话说:上述计时是通过testrepeat 100 1000
和获得的testrepeat 1000000 1000
#!/usr/bin/env bash
title() { printf '%s:\t' "$1"; }
TIMEFORMAT=$'%6Rs'
# The number of repetitions of the input chars. to produce
COUNT_REPETITIONS=${1?Arguments: <charRepeatCount> [<testRunCount>]}
# The number of test runs to perform to derive the average timing from.
COUNT_RUNS=${2:-1}
# Discard the (stdout) output generated by default.
# If you want to check the results, replace '/dev/null' on the following
# line with a prefix path to which a running index starting with 1 will
# be appended for each test run; e.g., outFilePrefix='outfile', which
# will produce outfile1, outfile2, ...
outFilePrefix=/dev/null
{
outFile=$outFilePrefix
ndx=0
title '[M, P] printf %.s= [dogbane]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
# !! In order to use brace expansion with a variable, we must use `eval`.
eval "
time for (( n = 0; n < COUNT_RUNS; n++ )); do
printf '%.s=' {1..$COUNT_REPETITIONS} >"$outFile"
done"
title '[M ] echo -n - arithmetic loop [Eliah Kagan]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
for ((i=0; i<COUNT_REPETITIONS; ++i)); do echo -n =; done >"$outFile"
done
title '[M ] echo -n - brace expansion loop [eugene y]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
# !! In order to use brace expansion with a variable, we must use `eval`.
eval "
time for (( n = 0; n < COUNT_RUNS; n++ )); do
for i in {1..$COUNT_REPETITIONS}; do echo -n =; done >"$outFile"
done
"
title '[M ] printf + sed [user332325 (comment)]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
printf "%${COUNT_REPETITIONS}s" | sed 's/ /=/g' >"$outFile"
done
title '[S ] printf + tr [user332325]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
printf "%${COUNT_REPETITIONS}s" | tr ' ' '=' >"$outFile"
done
title '[S ] head + tr [eugene y]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
head -c $COUNT_REPETITIONS < /dev/zero | tr '\0' '=' >"$outFile"
done
title '[M ] seq -f [Sam Salisbury]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
seq -f '=' -s '' $COUNT_REPETITIONS >"$outFile"
done
title '[M ] jot -b [Stefan Ludwig]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
jot -s '' -b '=' $COUNT_REPETITIONS >"$outFile"
done
title '[M ] yes + head + tr [Digital Trauma]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
yes = | head -$COUNT_REPETITIONS | tr -d '\n' >"$outFile"
done
title '[M ] Perl [sid_com]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
perl -e "print \"=\" x $COUNT_REPETITIONS" >"$outFile"
done
title '[S, P] dd + tr [mklement0]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
dd if=/dev/zero bs=$COUNT_REPETITIONS count=1 2>/dev/null | tr '\0' "=" >"$outFile"
done
# !! On OSX, awk is BSD awk, and mawk and gawk were installed later.
# !! On Linux systems, awk may refer to either mawk or gawk.
for awkBin in awk mawk gawk; do
if [[ -x $(command -v $awkBin) ]]; then
title "[M ] $awkBin"' - $(count+1)="=" [Steven Penny (variant)]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
$awkBin -v count=$COUNT_REPETITIONS 'BEGIN { OFS="="; $(count+1)=""; print }' >"$outFile"
done
title "[M, P] $awkBin"' - while loop [Steven Penny]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
$awkBin -v count=$COUNT_REPETITIONS 'BEGIN { while (i++ < count) printf "=" }' >"$outFile"
done
fi
done
title '[M ] printf + bash global substr. replacement [Tim]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
# !! In Bash 4.3.30 a single run with repeat count of 1 million took almost
# !! 50 *minutes*(!) to complete; n Bash 3.2.57 it's seemingly even slower -
# !! didn't wait for it to finish.
# !! Thus, this test is skipped for counts that are likely to be much slower
# !! than the other tests.
skip=0
[[ $BASH_VERSINFO -le 3 && COUNT_REPETITIONS -gt 1000 ]] && skip=1
[[ $BASH_VERSINFO -eq 4 && COUNT_REPETITIONS -gt 10000 ]] && skip=1
if (( skip )); then
echo 'n/a' >&2
else
time for (( n = 0; n < COUNT_RUNS; n++ )); do
{ printf -v t "%${COUNT_REPETITIONS}s" '='; printf %s "${t// /=}"; } >"$outFile"
done
fi
} 2>&1 |
sort -t$'\t' -k2,2n |
awk -F $'\t' -v count=$COUNT_RUNS '{
printf "%s\t", $1;
if ($2 ~ "^n/a") { print $2 } else { printf "%.4f\n", $2 / count }}' |
column -s$'\t' -t
In order to use brace expansion with a variable, we must use `eval`
👍–
有多种方法可以做到这一点。
使用循环:
括号扩展可与整数文字一起使用:
for i in {1..100}; do echo -n =; done
类似于C的循环允许使用变量:
start=1
end=100
for ((i=$start; i<=$end; i++)); do echo -n =; done
使用printf
内置的:
printf '=%.0s' {1..100}
在此处指定精度会截断字符串以适合指定的宽度(0
)。当printf
重新使用格式字符串以使用所有参数时,这只会打印"="
100次。
使用head
(printf
,等等)和tr
:
head -c 100 < /dev/zero | tr '\0' '='
printf %100s | tr " " "="
head
/ tr
解决方案的++,即使在重复次数很高的情况下也能很好地工作(小的警告:head -c
不符合POSIX,但是BSD和GNU都head
实现了它);尽管其他两种解决方案在这种情况下会很慢,但它们的确也具有使用多字符字符串的优势。
yes
和head
-有用的,如果你想一定数量的新行的:yes "" | head -n 100
。tr
可以使其打印任何字符:yes "" | head -n 100 | tr "\n" "="; echo
dd if=/dev/zero count=1 bs=100000000 | tr '\0' '=' >/dev/null
是:比head -c100000000 < /dev/zero | tr '\0' '=' >/dev/null
版本慢得多。当然,您必须使用100M +的块大小来合理地测量时间差。100M字节分别耗时1.7 s和1 s,分别显示了两个版本。我摘下了tr,然后将其转储到该版本中,得到十亿字节的版本为/dev/null
0.287 s,head
版本为0.675 s dd
。
dd if=/dev/zero count=1 bs=100000000 | tr '\0' '=' >/dev/null
=> 0,21332 s, 469 MB/s
; 对于:dd if=/dev/zero count=100 bs=1000000| tr '\0' '=' >/dev/null
=> 0,161579 s, 619 MB/s
;
我刚刚找到了一种使用seq的非常简单的方法:
更新:这在BSD上有效 seq
OS X附带的BSD。YMMV和其他版本
seq -f "#" -s '' 10
将打印“#”十次,如下所示:
##########
-f "#"
设置格式字符串以忽略数字并仅打印 #
每个。-s ''
将分隔符设置为空字符串以删除seq在每个数字之间插入的换行符-f
,并-s
似乎是很重要的。编辑:这是在一个方便的功能...
repeat () {
seq -f $1 -s '' $2; echo
}
你可以这样称呼...
repeat "#" 10
注意:如果要重复,#
则引号很重要!
seq: format ‘#’ has no % directive
。 seq
用于数字,而不是字符串。参见gnu.org/software/coreutils/manual/html_node/seq-invocation.html
seq
被巧妙地用于复制字符串:传递给-f
-通常用于格式化生成的数字的格式字符串-仅包含要在此处复制的字符串,因此输出仅包含该字符串的副本。不幸的是,GNU seq
坚持在格式字符串中存在数字格式,这是您看到的错误。
"$1"
(双引号),因此您也可以传入'*'
带有嵌入式空格的字符,例如和字符串。最后,如果您想使用%
,则必须将其加倍(否则seq
会认为它是格式规范的一部分,例如%f
);使用"${1//%/%%}"
会照顾的。由于(如您所述)您正在使用BSD seq
,因此它通常可在类似BSD的OS(例如FreeBSD)上运行-相比之下,它将在使用GNU的Linux上不起作用。 seq
这是两种有趣的方式:
ubuntu @ ubuntu:〜$是= | 头-10 | 粘贴-s -d''- ========== ubuntu @ ubuntu:〜$是= | 头-10 | tr -d“ \ n” ========== ubuntu @ ubuntu:〜$
请注意,这两者是有细微差别的- paste
方法以新行结尾。该tr
方法没有。
paste
莫名其妙地要求-d '\0'
指定一个空的定界符,并且失败-d ''
- -d '\0'
应该与所有POSIX兼容的paste
实现一起工作,并且实际上也与GNU一起 工作paste
。
yes | mapfile -n 100 -C 'printf = \#' -c 1
time yes = | head -500 | paste -s -d '\0' -; time yes | mapfile -n 500 -C 'printf = \#' -c 1
。但是,更重要的是:如果您printf
printf '%.s=' $(seq 500)
没有简单的方法。避免使用printf
和替换循环。
str=$(printf "%40s")
echo ${str// /rep}
# echoes "rep" 40 times.
repl = 100
(不输出结尾\n
):repl() { local ts=$(printf "%${2}s"); printf %s "${ts// /$1}"; }
如果您希望POSIX以及echo
和printf
和/或Shell的不同实现之间的一致性和一致性,而不仅仅是bash
:
seq(){ n=$1; while [ $n -le $2 ]; do echo $n; n=$((n+1)); done ;} # If you don't have it.
echo $(for each in $(seq 1 100); do printf "="; done)
...将产生perl -E 'say "=" x 100'
几乎与所有地方相同的输出。
seq
不是POSIX实用程序(尽管BSD和Linux系统具有它的实现)-您可以使用while
循环来执行POSIX Shell算术,如@ Xennex81的答案(使用printf "="
,如您正确建议的那样,而不是echo -n
)。
cal
是POSIX。seq
不是。无论如何,我将添加一个RYO函数,而不是使用while循环重写答案(如您所说,这已经在其他答案中了)。这样更具教育意义;-)。
没有eval
,没有子shell,没有外部工具,没有括号扩展的纯Bash方式(即,您可以在变量中重复数字):
如果您得到一个n
扩展为(非负)数字的变量和一个变量pattern
,例如,
$ n=5
$ pattern=hello
$ printf -v output '%*s' "$n"
$ output=${output// /$pattern}
$ echo "$output"
hellohellohellohellohello
您可以使用以下功能:
repeat() {
# $1=number of patterns to repeat
# $2=pattern
# $3=output variable name
local tmp
printf -v tmp '%*s' "$1"
printf -v "$3" '%s' "${tmp// /$2}"
}
这样设置:
$ repeat 5 hello output
$ echo "$output"
hellohellohellohellohello
对于这个小技巧,我们在以下方面使用printf
了很多:
-v varname
:printf
将格式字符串的内容放入变量中,而不是打印到标准输出中varname
。printf
将使用参数打印相应数量的空格。例如,printf '%*s' 42
将打印42个空格。${var// /$pattern}
将扩展为,将var
所有空格替换为$pattern
。您还可以通过使用间接扩展来消除函数中的tmp
变量repeat
:
repeat() {
# $1=number of patterns to repeat
# $2=pattern
# $3=output variable name
printf -v "$3" '%*s' "$1"
printf -v "$3" '%s' "${!3// /$2}"
}
bash
在参数扩展(${var//old/new}
)的上下文中的全局字符串替换操作特别慢:至少在3.2 GHz英特尔酷睿i5机器上的OSX 10.10.3系统上,bash的运行速度极其缓慢,bash的运行3.2.57
速度极慢4.3.30
:计数为1,000,则慢速(3.2.57
)/快速(4.3.30
):0.1 / 0.004秒。将计数增加到10,000会产生截然不同的数字: repeat 10000 = var
bash大约需要80秒(!),bash 3.2.57
大约需要0.3秒4.3.30
(比on快得多3.2.57
,但仍然很慢)。
#!/usr/bin/awk -f
BEGIN {
OFS = "="
NF = 100
print
}
要么
#!/usr/bin/awk -f
BEGIN {
while (z++ < 100) printf "="
}
awk 'BEGIN { while (c++ < 100) printf "=" }'
。裹成参数化shell函数(调用如repeat 100 =
,例如): repeat() { awk -v count="$1" -v txt=".$2" 'BEGIN { txt=substr(txt, 2); while (i++ < count) printf txt }'; }
。(虚设.
前缀炭和互补substr
呼叫需要以围绕工作在BSD的错误awk
,其中,传递变量值,该值开始与=
断命令。)
NF = 100
解决方案是很聪明的(虽然得到100 =
,则必须使用NF = 101
)。需要注意的是,它使BSD崩溃awk
(但使用会很快,gawk
甚至更快mawk
),并且POSIX既没有讨论分配给NF
,也没有讨论在BEGIN
块中使用字段。您也可以通过awk
稍作调整使其在BSD中工作:(awk 'BEGIN { OFS = "="; $101=""; print }'
但奇怪的是,在BSD中awk
,它不比循环解决方案快)。作为一个参数壳溶液:repeat() { awk -v count="$1" -v txt=".$2" 'BEGIN { OFS=substr(txt, 2); $(count+1)=""; print }'; }
。
original-awk
类似BSD的AWK,这也被报道崩溃,如果你想尝试这种旧的awk Linux下的名称。请注意,崩溃通常是查找可利用错误的第一步。这个答案是如此促进不安全的代码。
original-awk
是非标准且不建议使用
awk NF=100 OFS='=' <<< ""
(使用bash
和gawk
)
我想这个问题的最初目的是仅使用Shell的内置命令来执行此操作。因此,for
循环和printf
s就合法,同时rep
,perl
和也jot
低于不肯。尽管如此,以下命令
jot -s "/" -b "\\" $((COLUMNS/2))
例如,在 \/\/\/\/\/\/\/\/\/\/\/\/
jot -s '' -b '=' 100
。需要注意的是,虽然附带了包括OSX在内的类似BSD的平台jot
,但Linux发行版却没有。
apt install athena-jot
将提供jot
。
正如其他人所说,在bash中,括号扩展在参数扩展之前,因此范围只能包含文字。并提供干净的解决方案,但即使在每个系统上使用相同的外壳,也不能完全移植到一个系统中。(尽管越来越多;例如,在FreeBSD 9.3及更高版本中。){m,n}
seq
jot
seq
eval
和其他形式的间接访问始终有效,但有些不雅。
幸运的是,bash 支持C风格的循环(仅适用于算术表达式)。因此,这是一种简洁的“纯bash”方式:
repecho() { for ((i=0; i<$1; ++i)); do echo -n "$2"; done; echo; }
这将重复次数作为第一个参数,将要重复的字符串(如问题描述中的单个字符)作为第二个参数。repecho 7 b
输出bbbbbbb
(由换行符终止)。
丹尼斯·威廉姆森(Dennis Williamson)在四年前对在shell脚本中创建重复字符字符串的出色回答中就给出了这种解决方案。我的函数体与那里的代码略有不同:
由于此处的重点是重复单个字符且shell是bash,因此使用echo
代替可能是安全的printf
。而且我读到该问题的问题描述是表示倾向于使用echo
。上面的函数定义在bash和ksh93中起作用。尽管它printf
具有更高的可移植性(通常应用于此类操作),但echo
可以说的语法更具可读性。
一些shell的echo
内建函数-
本身将其解释为一个选项-尽管-
使用stdin作为输入的通常含义对而言是毫无意义的echo
。zsh做到了。而且肯定存在echo
无法识别的-n
,因为它不是标准的。(许多Bourne风格的shell根本不接受C风格的循环,因此echo
不需要考虑它们的行为。)
这里的任务是打印序列。在那里,是将其分配给变量。
如果$n
期望的重复次数是,则不必重复使用它,而您想要的则更短一些:
while ((n--)); do echo -n "$s"; done; echo
n
必须为变量-这种方式不适用于位置参数。$s
是要重复的文本。
printf "%100s" | tr ' ' '='
是最佳的。
zsh
同时使用。循环中的回声方法对于较小的重复计数效果很好,但是对于较大的重复计数,有基于实用程序的 POSIX兼容替代方法,如@Slomojo的评论所证明。
echo
内置的support -n
。您所说的精神是绝对正确的。至少在非交互使用中,printf
应该几乎总是首选echo
。但是我认为echo
对一个提出问题的答案给出任何答案并提供足够的信息以知道它会起作用是不适当的或具有误导性。另请注意,POSIX本身不保证支持((n--))
(不带$
)。
Python无处不在,并且在任何地方都可以使用。
python -c "import sys; print('*' * int(sys.argv[1]))" "=" 100
字符和计数作为单独的参数传递。
python -c "import sys; print(sys.argv[1] * int(sys.argv[2]))" "=" 100
重复任意字符串n次的另一种方法是:
优点:
缺点:
yes
命令。#!/usr/bin/sh
to_repeat='='
repeat_count=80
yes "$to_repeat" | tr -d '\n' | head -c "$repeat_count"
用ANSI终端和US-ASCII字符重复。您可以使用ANSI CSI转义序列。这是重复字符的最快方法。
#!/usr/bin/env bash
char='='
repeat_count=80
printf '%c\e[%db' "$char" "$repeat_count"
或静态地:
打印80行=
:
printf '=\e[80b\n'
局限性:
repeat_char
ANSI CSI序列。repeat_char
ANSI CSI序列扩展为重复的字符。这是我在linux中跨屏幕打印一行字符的方法(基于终端/屏幕宽度)
printf '=%.0s' $(seq 1 $(tput cols))
说明:
按给定序列打印等号多次:
printf '=%.0s' #sequence
使用命令的输出(这是一个称为Command Substitution的bash功能):
$(example_command)
给一个序列,我以1到20为例。在最终命令中,使用tput命令代替20:
seq 1 20
给出终端当前使用的列数:
tput cols
for i in {1..100}
do
echo -n '='
done
echo
提议的Python解决方案的更优雅替代品可能是:
python -c 'print "="*(1000)'
如果您想重复一个字符n次为n个可变次数(例如取决于字符串的长度),则可以执行以下操作:
#!/bin/bash
vari='AB'
n=$(expr 10 - length $vari)
echo 'vari equals.............................: '$vari
echo 'Up to 10 positions I must fill with.....: '$n' equal signs'
echo $vari$(perl -E 'say "=" x '$n)
它显示:
vari equals.............................: AB
Up to 10 positions I must fill with.....: 8 equal signs
AB========
length
expr
您可能会表示不予合作n=$(expr 10 - ${#vari})
; 但是,使用Bash的算术扩展更为简单高效n=$(( 10 - ${#vari} ))
。另外,您的答案的核心是OP正在寻找Bash 替代品的 Perl方法 。
function repeatString()
{
local -r string="${1}"
local -r numberToRepeat="${2}"
if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]]
then
local -r result="$(printf "%${numberToRepeat}s")"
echo -e "${result// /${string}}"
fi
}
样品运行
$ repeatString 'a1' 10
a1a1a1a1a1a1a1a1a1a1
$ repeatString 'a1' 0
$ repeatString '' 10
参考库位于:https : //github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash
我的答案有点复杂,可能还不完美,但是对于那些希望输出大量数字的人来说,我能够在3秒钟内完成大约一千万次操作。
repeatString(){
# argument 1: The string to print
# argument 2: The number of times to print
stringToPrint=$1
length=$2
# Find the largest integer value of x in 2^x=(number of times to repeat) using logarithms
power=`echo "l(${length})/l(2)" | bc -l`
power=`echo "scale=0; ${power}/1" | bc`
# Get the difference between the length and 2^x
diff=`echo "${length} - 2^${power}" | bc`
# Double the string length to the power of x
for i in `seq "${power}"`; do
stringToPrint="${stringToPrint}${stringToPrint}"
done
#Since we know that the string is now at least bigger than half the total, grab however many more we need and add it to the string.
stringToPrint="${stringToPrint}${stringToPrint:0:${diff}}"
echo ${stringToPrint}
}
大多数现有的解决方案都依赖于{1..10}
语法的支持壳,这是bash
-和zsh
-特定的,并且不工作tcsh
或OpenBSD的ksh
和大多数非的bashsh
。
以下内容适用于OS X和任何外壳中的所有* BSD系统;实际上,它可以用于生成各种装饰空间的整体矩阵:
$ printf '=%.0s' `jot 64` | fold -16
================
================
================
================$
可悲的是,我们没有换行符。printf '\n'
折叠后可以额外固定:
$ printf "=%.0s" `jot 64` | fold -16 ; printf "\n"
================
================
================
================
$
参考文献:
我的建议(接受n的变量值):
n=100
seq 1 $n | xargs -I {} printf =