## 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-103110-113120-123130-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:
`100101102103110111112113120121122123130131132133`

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,103110,111,112,113120,121,122,123130,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-103110-113120-123130-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

Mahesh Kharvi said...

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

@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"