Boirebista
Boirebista

Reputation: 40

bash - how do I use 2 numbers on a line to create a sequence

I have this file content:

2450TO3450  
3800  
4500TO4560  

And I would like to obtain something of this sort:

2450  
2454  
2458  
...  
3450  
3800  
4500  
4504  
4508  
..  
4560  

Basically I would need a one liner in sed/awk that would read the values on both sides of the TO separator and inject those in a seq command or do the loop on its own and dump it in the same file as a value per line with an arbitrary increment, let's say 4 in the example above.

I know I can use several one temp file, go the read command and sorts, but I would like to do it in a one liner starting with cat filename | etc. as it is already part of a bigger script.

Correctness of the input is guaranteed so always left side of TOis smaller than bigger side of it.

Thanks

Upvotes: 2

Views: 189

Answers (5)

potong
potong

Reputation: 58440

This might work for you (GNU sed):

sed -r 's/(.*)TO(.*)/seq \1 4 \2/e' file

This evaluates the RHS of the substitution command if the LHS contains TO.

Upvotes: 0

Jay jargot
Jay jargot

Reputation: 2868

Give a try to this:

sed 's/TO/ /' file.txt | while read first second; do if [ ! -z "$second" ] ; then seq $first 4 $second; else printf "%s\n" $first; fi; done

sed is used to replace TO with space char.

read is used to read the line, if there are 2 numbers, seq is used to generate the sequence. Otherwise, the uniq number is printed.

Upvotes: 0

dawg
dawg

Reputation: 103884

Given:

txt="2450TO3450  
3800  
4500TO4560"

You can do:

echo "$txt" | awk -F TO '{$2<$1 ? t=$1 : t=$2; for(i=$1; i<=t; i++) print i}'

If you want an increment greater than 1:

echo "$txt" | awk -F TO -v p=4 '{$2<$1 ? t=$1 : t=$2; for(i=$1; i<=t; i+=p) print i}'

Upvotes: 0

Mark Setchell
Mark Setchell

Reputation: 207520

Like this:

awk -F'TO' -v inc=4 'NF==1{print $1;next}{for(i=$1;i<=$2;i+=inc)print i}' file

or, if you like starting with cat:

cat file | awk -F'TO' -v inc=4 'NF==1{print $1;next}{for(i=$1;i<=$2;i+=inc)print i}'

Upvotes: 2

Wander Nauta
Wander Nauta

Reputation: 19625

Something like this might work:

awk -F TO '{system("seq " $1 " 4 " ($2 ? $2 : $1))}'

This would tell awk to system (execute) the command seq 10 4 10 for lines just containing 10 (which outputs 10), and something like seq 10 4 40 for lines like 10TO40. The output seems to match your example.

Upvotes: 1

Related Questions