Is there any built-in Linux command that allows to output a string that is n times an input string??
17 Answers
adrian@Fourier:~$ printf 'HelloWorld\n%.0s' {1..5}
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$
- 3,436
Here's an old-fashioned way that's pretty portable:
yes "HelloWorld" | head -n 10
This is a more conventional version of Adrian Petrescu's answer using brace expansion:
for i in {1..5}
do
echo "HelloWorld"
done
That's equivalent to:
for i in 1 2 3 4 5
This is a little more concise and dynamic version of pike's answer:
printf -v spaces '%*s' 10 ''; printf '%s\n' ${spaces// /ten}
- 111,445
You can use a trick. Echoing an empty variable does not print anything. So you can write:
echo word$wojek{1..100}
If $wojek1 $wojek2 ... $wojek100 are non-existing variables you will get your word repeated 100 times without anything else.
- 25,513
- 408
- 4
- 4
This can be parameterized and doesn't require a temp variable, FWIW:
printf "%${N}s" | sed 's/ /blah/g'
Or, if $N is the size of a bash array:
echo ${ARR[@]/*/blah}
- 309
- 2
- 2
Quite a few good ways already mentioned. Can't forget about good old seq though:
[john@awesome]$for i in `seq 5`; do echo "Hi";done Hi Hi Hi Hi Hi
Repeat n times, just put n-1 commas between {}:
$ echo 'helloworld'{,,}
helloworld helloworld helloworld
Repeats 'helloworld' twice after the first echo.
- 283
- 13,200
Perhaps another way that is more general and useful for you:
adrian@Fourier:~$ n=5
adrian@Fourier:~$ for (( c=1; c<=n; c++)) ; do echo "HelloWorld" ; done
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$
The bash shell is more powerful than most people think :)
- 3,436
I've experienced broken pipe warnings with the yes solution, so here's another good alternative:
$ seq 4 | sed -E 's/.+/foo/'
foo
foo
foo
foo
- 190
based on what @pike was hinting at
for every character in string echo string
echo ${target//?/$replace}
An example of a heading underlined with = characters
export heading='ABCDEF';
export replace='=';
echo -e "${heading}\n${heading//?/$replace}"
will output
ABCDEF
======
This seems to port between linux and OS X and that makes me happy.
nJoy!
- 520
- 5
- 6
POSIX AWK:
#!/usr/bin/awk -f
function str_repeat(s1, n1) {
s2 = ""
for (n2 = 1; n2 <= n1; n2++) {
s2 = s2 s1
}
return s2
}
BEGIN {
s3 = str_repeat("Sun", 5)
print s3
}
Or PHP:
<?php
$s3 = str_repeat('Sun', 5);
echo $s3, "\n";
- 1
If you're on BSD, you can just use seq.
$ seq -f "Hello, world" 5
Hello, world
Hello, world
Hello, world
Hello, world
Hello, world
Assuming you want something like Perl's x operator, where you don't automatically get a newline between repetitions:
x() {
# usage: x string num
for i in $(seq 1 $2); do printf "%s" "$1"; done
# print a newline only if the string does not end in a newline
[[ "$1" == "${1%$'\n'}" ]] && echo ""
}
x Hi 10 # ==> HiHiHiHiHiHiHiHiHiHi
x $'Hello World!\n' 3
I explicitly used a for loop because you can't write {1..$n} in bash: brace expansion is done before variable substitution.
- 27,524
Not exactly built in to linux, but if you have python installed..
python
>>>var = "string"
>>>var*n
Or in one line, as commenter suggested:
python -c 'print "This is a test.\n" * 10'
- 2,478
line="==========================="
line=${line:0:10}
${line//"="/"ten "}
outputs
ten ten ten ten ten ten ten ten ten ten
- 363
On macOS and BSD you can use jot
# Print 5 lines of `HelloWorld`
jot -b "HelloWorld" 5
Print HelloWorld 5 times without newlines
jot -s "" -b "HelloWorld" 5
Print Hello 5 times using a different separator which is World instead of newline
jot -s "World" -b "Hello" 5
On Linux you can install athena-jot to get it
Like yes, this solution allows for any number of repetition $N and is very fast although not extremely fast like yes or customized native solutions with SIMD and splice which can achieve tens of GBs of data per second, but it's still significantly faster than most other solutions
With yes you can print without new lines like this
$ N=10000000
$ WORD=HelloWorld
$ yes $WORD | tr -d '\n' | head -c $(($N * ${#WORD}))
Benchmark:
Looping directly with the shell is slow for obvious reasons, therefore will be unsuitable for huge $N values. You'll always need some external tools like yes, sed, tr... for fast output. The brace expansion trick {1..$N} also completely fails when $N is large due to argument list too long error and using variable string replacement like in commonpike's answer will make the shell give up soon due to lack of memory or the OOM will kick in
Below is some results when printing the word followed by a new line
$ time bash -c "echo $WORD\$_{1..$N} >/dev/null"
real 0m15.863s
user 0m15.189s
sys 0m0.646s
$ time bash -c "for i in {1..$N}; do echo $WORD; done >/dev/null"
real 0m42.728s
user 0m38.029s
sys 0m4.673s
$ time bash -c "for i in $(seq $N); do echo $WORD; done >/dev/null"
real 0m43.073s
user 0m39.349s
sys 0m4.507s
As you can see they're very slow. External tools will blow them out
$ time bash -c "printf %${N}s | sed 's/ /$WORD\n/g' >/dev/null"
real 0m1.913s
user 0m1.847s
sys 0m0.071s
$ time jot -b $WORD $N >/dev/null
real 0m1.262s
user 0m1.255s
sys 0m0.005s
$ time yes $WORD | head -n $N >/dev/null
real 0m0.912s
user 0m0.903s
sys 0m0.031s
$ time gyes $WORD | head -n $N >/dev/null
real 0m0.930s
user 0m0.947s
sys 0m0.090s
$ time yes $WORD | ghead -n $N >/dev/null
real 0m0.246s
user 0m0.138s
sys 0m0.213s
$ time gyes $WORD | ghead -n $N >/dev/null
real 0m0.258s
user 0m0.175s
sys 0m0.242s
I'm doing these tests on macOS and in the last 4 tests you can see how terrible BSD tools are compared to GNU tools (prefixed with g due to name clashing with the default BSD tools), even though they're still far faster than the shell
The above cases are with a trailing new line, and when printing without new lines GNU tools also leave BSD tools in the dust
$ time yes $WORD | tr -d '\n' | ghead -c 300M >/dev/null
real 0m26.763s
user 0m26.857s
sys 0m0.381s
$ time gyes $WORD | tr -d '\n' | ghead -c 300M >/dev/null
real 0m27.972s
user 0m28.142s
sys 0m0.598s
$ time yes $WORD | gtr -d '\n' | ghead -c 300M >/dev/null
real 0m1.353s
user 0m0.609s
sys 0m0.981s
$ time gyes $WORD | gtr -d '\n' | ghead -c 300M >/dev/null
real 0m0.980s
user 0m0.785s
sys 0m1.095s
Maybe someone else can test with busybox or musl tools
- 30,396
- 15
- 136
- 260
Try this one:
echo $(for i in $(seq 1 100); do printf "-"; done)
Will create (a hundred dash):
- 35