8

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?

4
  • 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? Commented Jan 5, 2019 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. Commented Jan 9, 2019 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. Commented Jan 9, 2019 at 20:10
  • If any of the answers solved your problem, please accept it by clicking the checkmark next to it. Thank you! Commented Jan 13, 2019 at 15:15

7 Answers 7

11

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.

16
  • 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. Commented Jan 3, 2019 at 20:21
  • 3
    @GreenMatt of course, if you need portability, you should also avoid using echo. Commented Jan 3, 2019 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. Commented Jan 3, 2019 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. Commented Jan 3, 2019 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. Commented Jan 3, 2019 at 22:35
6

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

4
  • 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". Commented Jan 3, 2019 at 20:34
  • Ah yes, I never think of tr. Commented Jan 3, 2019 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) Commented Jan 4, 2019 at 2:43
  • My take on this: unix.stackexchange.com/a/492380/6622 Commented Jan 4, 2019 at 4:09
5

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

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 
0
1

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.

1

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 
0

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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.