Is there any built-in Linux command that allows to output a string that is n times an input string??
-
1By "built-in linux command" I assume you mean shell command, and since you don't mention which shell you're using, I assume it's bash. You can check this by typing "echo $SHELL" at the command line and you should get something similar to "/bin/bash" back. If you don't, you should edit your answer to specify what it does show. Cheers :) – Adrian Petrescu Dec 22 '09 at 3:12
-
7I tagged the question with "bash". I thought that would've been enough. – GetFree Dec 22 '09 at 3:27
-
1Related on Stack Overflow: stackoverflow.com/q/3211891/2157640 – Palec Nov 16 '14 at 14:33
adrian@Fourier:~$ printf 'HelloWorld\n%.0s' {1..5}
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$
-
7Could you explain how this works? I understand the printf command since it's the same as the one in C/C++. But I dont understand how the {1..5} is expanded and how that works in conjunction with the "%.0s" part. – GetFree Dec 22 '09 at 3:24
-
4It's a bit of a hack :) Try running "printf 'HelloWorld %d\n' 1 2 3 4 5" and it'll probably click for you. The %.0s flag is meant to do nothing, just be there to pick up arguments. Then, if bash gets more arguments than it has format specifiers, it will simply print out multiple copies, grabbing as many as it needs. So you get the effect. The output of "printf 'HelloWorld %d%d\n' 1 2 3 4 5 6" probably makes it even clearer. Hope this helps! – Adrian Petrescu Dec 22 '09 at 3:44
-
I see. It's the particular behavior of printf what allows the repetition – GetFree Dec 22 '09 at 3:53
-
1(I should note that, from a purely theoretical standpoint, this is probably the fastest solution since it uses a single shell primitive -- not any external processes. In reality though, let's face it, performance of bash scripts doesn't really matter :) – Adrian Petrescu Dec 22 '09 at 3:53
-
1What is specific to
printf
is that it will repeatedly apply excess arguments to the format string, "looping" for free. By "excess", I mean that there are more arguments than%
placeholders. – Dennis Williamson May 8 '12 at 20:38
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}
-
-
3One way is to pipe it through
sed -n 'H;${x;s/\n//gp}'
orsed -n ':t;${s/\n//gp};N;bt'
another is to doecho $(yes "HelloWorld" | head -n 10)
which adds a space between each copy of the string. Yet another way is to pipe it throughtr -d '\n'
which also eliminates the final newline. – Dennis Williamson Dec 22 '09 at 9:08 -
2
-
4
-
1@arnsholt: OK, I would use a
for
loop instead of spawning an external executable (yes
). Or capture it once and output it twice like:out=$(my-command); printf '%s\n' "$out" "$out"
(printf
will apply excess arguments sequentially) or other similar techniques. – Dennis Williamson Aug 3 '16 at 19:15
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
-
This one actually respects a zero, treating it as zero! (The
{i..j}
trick never returns an empty range.) – JellicleCat Oct 15 '16 at 2:48
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}
-
3This is the shortest POSIX 7 solution I have seen so far since
seq
,yes
and{1..5}
are not POSIX 7. – Ciro Santilli新疆棉花TRUMP BAN BAD Apr 10 '14 at 11:27 -
1You shouldn't mix data into
printf
's format specifier. What if the data contains format strings? This is the correct way to dynamically specify the "precision" (length):printf '%*s' "$N"
- make it a habit to enclose the format string in single quotes to prevent variable expansion there. – Dennis Williamson Jan 5 '19 at 14:22
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.
-
1
-
3Love it! Maybe using
$_
instead of$wojek
makes the intent clearer. – Mihai Todor Sep 4 '19 at 14:13
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 :)
-
-
2What forking are you referring to? The original answer requires none. The output of 'type printf' is 'printf is a shell builtin' and therefore runs within the original bash process. – CodeGnome Apr 17 '12 at 20:17
-
This is the only one so far (
yes
,printf
,for i in {1..5}
) that if then
is zero, it returns empty string without exist status of 1. Also due to the mathematical notation for comparison, it is easy to have offset by 1 (e.g by changing the<=
to<
) – Mehrad Mahmoudian Jun 19 '19 at 8:54
Repeat n
times, just put n-1
commas between {}
:
$ echo 'helloworld'{,,}
helloworld helloworld helloworld
Repeats 'helloworld' twice after the first echo.
-
5
-
3
-
this doesn't seem to let you put newlines in the string either (ie getting helloworld on their own lines) – TankorSmash Feb 1 '19 at 16:54
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";
I've experienced broken pipe warnings with the yes
solution, so here's another good alternative:
$ seq 4 | sed "c foo"
foo
foo
foo
foo
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!
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
-
2In
seq (GNU coreutils) 8.25
, this givesseq: format 'Hello, world' has no % directive
, forcing a formatting directive to be present. GNU coreutils are used e.g. n many Linux distributions and Cygwin. Including the info here for those missing the info that it works only in BSD seq. – Palec Jun 19 '17 at 10:08
line="==========================="
line=${line:0:10}
${line//"="/"ten "}
outputs
ten ten ten ten ten ten ten ten ten ten
-
Maybe a more verbose example: declare c='-----'; c=${c//${c:0:1}/$c}; echo $c # Prints "-" 25 times. – Stephen Niedzielski Jan 2 '13 at 23:02
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.
Try this one:
echo $(for i in $(seq 1 100); do printf "-"; done)
Will create (a hundred dash):
-
I like this answer, as when "n" is an environment var (e.g.
$n
), the curly-brace syntax doesn't work:n=10 && echo {1..$n}
produces{1..10}
, whereasecho {1..3}
produces1 2 3
. – Gordon Bean Oct 2 '20 at 22:37
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'
-
4Not really that useful, since it can't be easily integrated into shell scripts, etc. And since there's about a billion ways to do this in the shell itself, I see little reason to bring out the big guns (i.e Python) for it. – Adrian Petrescu Dec 22 '09 at 3:18
-
7I agree with your second point but not the fist...it's easy to integrate into a shell script: python -c 'print "This is a test.\n" * 10' – larsks Dec 22 '09 at 14:26
-