To create a column header, looking like:


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?

  • would you care to elaborate why you can't just echo 1234567890123456789? and why you need just 19 columns? and why the echo -n 0; seq -s '' 1 9 instead of seq -s '' 0 9? – pizdelect Jan 5 '19 at 18:42
  • @pizdelect: Q1 & 2: I'm looking for an expandable method that might be put in a scripts; Q3: Because I don't want a leading 0. – GreenMatt Jan 9 '19 at 19:39
  • Q1 & Q2. what do you want to expand it to? I explained in my answer how to make a header as wide as the terminal, without writing the numbers byte by byte. And that's easy to adapt to eg. a header like abcdeabcde.... Q3. the two commands from my comment are equivalent. – pizdelect Jan 9 '19 at 20:10
  • If any of the answers solved your problem, please accept it by clicking the checkmark next to it. Thank you! – Jeff Schaller Jan 13 '19 at 15:15

Assuming you just want to print 1234567890123456789, you can do it with:

$ printf "%s" $(seq 1 9) $(seq 0 9)

That won't have a trailing newline at all though, so maybe you prefer:

$ printf "%s" $(seq 1 9) $(seq 0 9) $'\n'

A few simpler choices if you don't need to use seq:

$ perl -le 'print 1..9,0,1..9'
$ printf "%s" {1..9} {0..9} $'\n'

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.

  • 1
    @GreenMatt ah, that depends. For extreme portability, you may as well just use the 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 3 '19 at 20:21
  • 3
    @GreenMatt of course, if you need portability, you should also avoid using echo. – terdon Jan 3 '19 at 20:25
  • 2
    @GreenMatt lol. Say what you like about Perl, you just can't beat it for text manipulation and it is extremely portable. – terdon Jan 3 '19 at 21:19
  • 1
    @Larry, not with that printf structure you can't, the format string gets repeated for each argument, but we only want one newline. – ilkkachu Jan 3 '19 at 22:22
  • 1
    @Larry, mm, the command you posted as a comment prints one digit per line. But I'm starting to think you should post that as an answer of your own if you want to refine or discuss it further. – ilkkachu Jan 3 '19 at 22:35

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 |.

  • 1
    Nice. This also has the benefit of being portable to most (all?) shells. I think the OP wants the final newline, so another option might be ( seq -s '' 1 9 ; echo -n 0 ; seq -s '' 1 9 ) | tr -d '\n' ; printf "\n". – terdon Jan 3 '19 at 20:34
  • Ah yes, I never think of tr. – GreenMatt Jan 3 '19 at 20:38
  • +1. Also, worth saying that BSD version of 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 4 '19 at 2:43
  • My take on this: unix.stackexchange.com/a/492380/6622 – poige Jan 4 '19 at 4:09

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
  • +1: The latter approach looks like everything it needs should be guaranteed to be available in any POSIX-y shell to me. – Charles Duffy Jan 3 '19 at 22:01

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)

To remove the trailing newline, just use a command execution:

 $ echo "test$(seq -s '' 9)no-newline"

Or capture it in a variable:

 $ var=$(seq -s '' 9); echo "${var}0${var}"

Or also:

 $ printf '%s' {{0..9},0,{0..9}}; echo

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

Of course, that won't work in csh (huh).

FYI: seq isn't portable (there's jot on *BSD, but it's quite different).


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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.