How can I repeat the character -
n times in shell? I have read and tried this, but this does not work for -
. It throws error invalid option
jot
can do it, with no bashisms:
jot -s '' -b - 100
seq
too, but not as well, it needs a tr
:
seq -s- 100 | tr -d '[0-9]'
This throws an error:
$ printf '-%.0s' {1..100}; echo ""
bash: printf: -%: invalid option
printf: usage: printf [-v var] format [arguments]
This works fine under bash
:
$ printf -- '-%.0s' {1..100}; echo ""
----------------------------------------------------------------------------------------------------
For other shells, try:
printf -- '-%.0s' $(seq 100); echo ""
The problem was the printf
expects that -
starts an option. As is common among Unix/POSIX utilities in this type of situation, --
signals to printf
to expect no more options.
Use a for
loop and number range:
for i in {1..10};
do echo "-";
done
Or on a single line:
for i in {1..10};
do echo -n "-";
done
which outputs ----------
.
EDIT: This was before your printf
edit.
This has been my goto for years... not AIX friendly though. Change the last character to change the repeating character which makes up the line
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' _
I would recommend using a traditional for
loop, as there is no need to spawn sub-processes or expand 100 arguments:
N=100
for((i = 0; i < $N; ++i)); do
printf -
done
It is curious that printf -%s
triggers "invalid option" but printf -
does not. To perhaps be extra safe, you could do printf %s -
.
John1024's helpful answer provides a generic solution that shows how to disambiguate options from operands for all POSIX-like utilities.
In the case at hand, the simplest solution is (works not only in bash
, but also in ksh
and zsh
):
printf '%.0s-' {1..100}
Placing %.0s
before the -
avoids the issue of an initial -
getting mistaken for an option.
Slightly optimized:[1]
printf '%.s-' {1..100}
[1] %.0s
is in practice the most portable form (to be fully portable, you must also avoid the brace expansion, {...}
).
%.s
, the equivalent shorthand form, is supported by bash
, ksh
, and dash
, but not zsh
<= v5.2 - even though it is equally POSIX-compliant : "The precision [the part after .
] shall take the form of a ( '.' ) followed by a decimal digit string; a null digit string is treated as zero."
As a side note: The question originally contained a benign (in Bash) typo that sparked a debate: %0.s
instead of %.0s
: %0.s
should effectively be the same as %.0s
, and for that matter, the same as %.s
and %0.0s
(all effectively request: print a [minimum zero-width] field filled with a zero-length string), but in practice isn't: zsh
<= v5.2 doesn't handle %0.s
correctly (again, due to the .s
part).
Similarly, the GNU printf
external-utility implementation (/usr/bin/printf
), as of GNU coreutils v8.24, reports an error with %0.s
, because it generally doesn't accept a field width of 0
with s
: invalid conversion specification
- this matters for lesser-known shells that don't provide printf
as a builtin. Note that the BSD/OSX implementation does not have this problem.
Both zsh
's (<= v5.2) behavior with %.s
and GNU /usr/bin/printf
's behavior with %0s
are deviations from the POSIX spec that smell like bugs.
This question asks about zsh
's behavior regarding %.s
, and the bug has since been confirmed and reported as fixed via a post-v5.2 commit that has yet to be released as of this writing.