To create a column header, looking like:
1234567890123456789
I (am trying to) use seq and echo:
seq -s '' 1 9 ; echo -n 0; seq -s '' 1 9
However, seq outputs a newline after each run. How can I avoid that?
Assuming you just want to print 1234567890123456789
, you can do it with:
$ printf "%s" $(seq 1 9) $(seq 0 9)
1234567890123456789$
That won't have a trailing newline at all though, so maybe you prefer:
$ printf "%s" $(seq 1 9) $(seq 0 9) $'\n'
1234567890123456789
$
A few simpler choices if you don't need to use seq
:
$ perl -le 'print 1..9,0,1..9'
1234567890123456789
$ printf "%s" {1..9} {0..9} $'\n'
1234567890123456789
Since you mentioned portability, I recommend you use the perl
approach, or if you are likely to encounter systems without perl
, and yet need the same command to run in shells including bash
, sh
, dash
, tcsh
etc, try Kamil's approach.
perl
one which is shell-agnostic. The printf "%s" $(seq 1 9) $(seq 0 9)
will work in any POSIX shell, including sh
and dash
, but the printf "%s" $(seq 1 9) $(seq 0 9) $'\n'
will fail in dash
. Note that it does work in sh
(or at least in bash
running as sh
, so in POSIX mode), I assume you're running Ubuntu or a simmilar system whose sh
is actually dash
. tcsh
is a strange one and not even trying to be POSIX so don't expect any of the shell-based approaches to work there.
– terdon
Jan 03 '19 at 20:21
echo
.
– terdon
Jan 03 '19 at 20:25
printf "%b" $(seq 1 9) $(seq 0 9) '\n'
should work in dash (%b
is POSIX if I didn't misread)
– ilkkachu
Jan 03 '19 at 21:50
$'\n'
) that doesn't work, and the '\n'
just prints a literal \n
, I think. I'm on mobile now so I can't check though.
– terdon
Jan 03 '19 at 21:55
printf %b
processes the escapes within printf
, so $'..'
isn't needed. printf %s
of course doesn't do that.
– ilkkachu
Jan 03 '19 at 21:56
$()
form of command substitution, 2. the ANSI string expansion.
@ilkkachu: "%b" does expand substituted newlines, but you can also include it in the format string itself.
– Larry
Jan 03 '19 at 22:19
printf
structure you can't, the format string gets repeated for each argument, but we only want one newline.
– ilkkachu
Jan 03 '19 at 22:22
seq
commands in a single argument, like in my example.
Except for the backslash before the first seq
, which is just stupid, I left it in somehow.
– Larry
Jan 03 '19 at 22:27
perl -le 'print 1..9,0,1..9'
is nice - single process, instead of two as in printf
and seq
in command substitution
– Sergiy Kolodyazhnyy
Jan 03 '19 at 23:31
You can remove newlines from any stream with tr -d '\n'
. In your case
(seq -s '' 1 9 ; echo -n 0; seq -s '' 1 9) | tr -d '\n'
While other answers may concentrate on modifying your original approach, this is the way that should just remove newline characters regardless of what is before |
.
( seq -s '' 1 9 ; echo -n 0 ; seq -s '' 1 9 ) | tr -d '\n' ; printf "\n"
.
– terdon
Jan 03 '19 at 20:34
seq
does treat -s ''
more fully than GNU's — no newline is printed even when it exits (they q-n wouldn't arise at all there)
– poige
Jan 04 '19 at 02:43
I assume you don't want just that particular string, but strings of incrementing digits with variable lengths. For that, it may be useful to be able to change the width by changing one number, instead of having to build it from multiple calls to seq
.
In Bash, you could use something like this (for a 19-long sequence):
for ((i=1; i <= 19; i++)); do printf "%d" "$(( i % 10 ))"; done; echo
This should work in a standard shell (and works in at least dash and busybox, anyway):
i=1; while [ "$i" -le 19 ]; do printf "%d" "$(( i % 10 ))"; i=$((i+1)); done; echo
Consider also:
printf '%d' $(seq -w 1 1 99 | cut -c2)
We generate the numbers 01..99, zero-padded (-w
), then strip off the tens-place. Those ones-place numbers are then sent to printf
to be printed individually.
To get your desired output, use 19
instead:
$ printf '%d' $(seq -w 1 1 19 | cut -c2)
1234567890123456789
When using tr
to get rid of trailing new-line it's worth realising that it deletes all occurrences of the characters given in its -d
option. Thus you can get it a bit more slim:
(seq 1 9; echo 0; seq 1 9) | tr -d '\n'
— even echo
doesn't need to have -n
anymore.
And for completeness sake: BSD's version of seq
when -s ''
specified doesn't produce new-line on its exit.
To remove the trailing newline, just use a command execution:
$ echo "test$(seq -s '' 9)no-newline"
test12345679no-newline
Or capture it in a variable:
$ var=$(seq -s '' 9); echo "${var}0${var}"
1234567890123456789
Or also:
$ printf '%s' {{0..9},0,{0..9}}; echo
1234567890123456789
I wonder why you don't just:
echo 1234567890123456789
And what's the point of printing just 19 columns instead of 20?
If you want it repeated (by default: for the whole width of the terminal)
chdr(){ c=${1:-$COLUMNS}; while [ "$c" -gt 0 ]; do printf '%.*s' "$c" 1234567890; c=$((c-10)); done; echo; }
chdr 17
12345678901234567
chdr
12345678901234567890123456789012345678901234567890123456789012345678901234567890
Of course, that won't work in csh
(huh).
FYI: seq
isn't portable (there's jot
on *BSD, but it's quite different).
echo 1234567890123456789
? and why you need just 19 columns? and why theecho -n 0; seq -s '' 1 9
instead ofseq -s '' 0 9
? – Jan 05 '19 at 18:42abcdeabcde...
. Q3. the two commands from my comment are equivalent. – Jan 09 '19 at 20:10