Search code examples
bashawksedseq

How to sequence lines in files if some lines are strings


I encountered a problem with bash, I started using it recently. I realize that lot of magic stuff can be done with just one line, as my previous question was solved by it. This time question is simple:

I have a file which has this format

2 2 10
custom
8 10
3 5 18
custom
1 5

some of the lines equal to string custom (it can be any line!) and other lines have 2 or 3 numbers in it. I want a file which will sequence the line with numbers but keep the lines with custom (order also must be the same), so desired output is

2 4 6 8 10
custom
8 9 10
3 8 13 18
custom
1 2 3 4 5

I also wish to overwrite input file with this one. I know that with seq I can do the sequencing, but I wish elegant way to do it on file.


Solution

  • You can use awk like this:

    awk '/^([[:blank:]]*[[:digit:]]+){2,3}[[:blank:]]*$/ {
       j = (NF==3) ? $2 : 1
       s=""
       for(i=$1; i<=$NF; i+=j)
          s = sprintf("%s%s%s", s, (i==$1)?"":OFS, i)
       $0=s
    } 1' file
    
    2 4 6 8 10
    custom
    8 9 10
    3 8 13 18
    custom
    1 2 3 4 5
    

    Explanation:

    • /^([[:blank:]]*[[:digit:]]+){2,3}[[:blank:]]*$/ - match only lines with 2 or 3 numbers.
    • j = (NF==3) ? $2 : 1 - set variable j to $2 if there are 3 columns otherwise set j to 1
    • for(i=$1; i<=$NF; i+=j) run a loop from 1st col to last col, increment by j
    • sprintf is used for formatting the generated sequence
    • 1 is default awk action to print each line