Saturday, November 7, 2009

Construct range from numbers - awk


Required:
With the numbers between 100 and 139 whose last digit is in between 0-3, construct the following output:

100-103
110-113
120-123
130-133

Step by step solution:
1) Numbers between 100 and 139 whose last digit is between 0-3

$ seq 100 139 | grep '[0-3]$'

Output:

100
101
102
103
110
111
112
113
120
121
122
123
130
131
132
133

2) Make them a single line with comma separated

$ seq 100 139 | grep '[0-3]$' | paste -sd,

Output:

100,101,102,103,110,111,112,113,120,121,122,123,130,131,132,133

3) Split the above into multiple sub-lines with each line containing 4 numbers

$ seq 100 139 | grep '[0-3]$' | paste -sd, | awk -F, '
{ for(i=1;i<=NF;i++)
{printf("%s%s",$i,i%4?",":"\n")}
}'

Output:

100,101,102,103
110,111,112,113
120,121,122,123
130,131,132,133

4) Print the first and last field

$ seq 100 139 | grep '[0-3]$' | paste -sd, | awk -F, '
{ for(i=1;i<=NF;i++)
{printf("%s%s",$i,i%4?",":"\n")}
}' | awk -F, '{print $1"-"$NF}'

Output:

100-103
110-113
120-123
130-133

I am sure there must be better ways to achieve this, please comment.

Related post:

- Break a line into multiple lines using awk and sed

4 comments:

Mahesh Kharvi said...

seq 100 10 139 | awk '{print $1"-"$1+3}'

Jadu Saikia said...

@Mahesh, yeah that's a quick and good solution. Thanks.

Ontureño said...

Just a suggestion, you can use the -s option in seq, instad of pasting the output. I mean, "seq 100 139 | paste -sd," has the same effect than "seq -s, 100 139"

Jadu Saikia said...

@Ontureño, yes you are correct; thanks for pointing this.

© Jadu Saikia www.UNIXCL.com