repeating a character using printf and appending a newline at the end
printf %.1s @{1..20} $'\n'
the shell expands the braces first, this is called "Brace Expansion".
@{1..20}
into @1 @2 @3 ...
and so on
Then the first byte of each parameter will be output, including the last argument $'\n'
consisting of one byte - the newline character
With zsh
:
printf '%s\n' ${(l[20][@])}
(using the l
left-padding parameter expansion flag. You could also use the r
ight padding one here).
Of course, you don't have to use printf
. You could also use print
or echo
here which do add a \n
by default. (printf '%s\n' "$string"
can be written print -r -- "$string"
or echo -E - "$string"
in zsh
, though if $string
doesn't contain backslashes and doesn't start with -
, that can be simplified to print "$string"
/echo "$string"
).
If the end-goal is to display a list of strings padded to the width of the screen, you'd do:
$ lines=(short 'longer text' 'even longer')
$ print -rC1 -- ${(ml[$COLUMNS][@][ ])lines}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ short
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ longer text
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ even longer
$ print -rC1 -- ${(mr[$COLUMNS][@][ ])lines}
short @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
longer text @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
even longer @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Where the m
flag causes zsh to take into account the display width of each character (like for those double-width characters above (which your browser may not render with exactly double-width, but your terminal should)).
print -rC1 --
is like printf '%s\n'
or print -rl --
to print one element per line except in the case where no arguments are passed to it (like when lines=()
) in which case it prints nothing instead of an empty line).
One printf
, ends in newline, variable size, works in dash, ksh, bash and zsh:
$ printf '%*.0s\n' 33 "" | tr " " "@"
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@