2

I have a file with lines such as:

....
pattern1 100 200 300
pattern2 300 400 400
pattern1 300 900 700
pattern1 200 500 900
...

As shown in the above example, there are some lines where pattern2 follows pattern1 but not all. I would like to match pattern1 then check if the next line has pattern2 and if it does, alter the next number field by multiplying it with a constant factor. I tried using getline with awk but it erases the lines with pattern1 from the resulting output:

awk '/pattern1/{getline; if($1==pattern2) $(NF-2)*=0.889848406214}1' infile.dat

Any suggestions how can I accomplish this without altering anything else in the input file.

  • How big are your files? Are you open to solutions that would load the entire file into memory? Are you open to non-awk solutions? Are there more than two patterns? Can you have pattern45 as well? – terdon Jan 28 '16 at 16:57
  • Files are medium sized, nothing too big. However, I would prefer awk solution because there is other processing done on the file which is done via awk. – mkc Jan 28 '16 at 19:37
3
awk '
  /pattern1/ { f = 1; print; next }
  f && /pattern2/ { $(NF-2) *= 0.889848406214 }
  { f = 0; print }
' <file
  • /pattern2/&&f{$(NF-2)*=0.889848406214}{print;f=0}/pattern1/{f=1} – Costas Jan 28 '16 at 17:41
  • @Costas: Cool, a little shorter. – cuonglm Jan 28 '16 at 17:49
2

Your approach is failing because getline immediately moves to the next line so the current one is lost. A simple solution would be to save the current line in a variable and then move to the next:

$ awk '{
        if(/pattern1/){
            l=$0; 
            getline; 
            if($1=="pattern2"){
                $(NF-2)*=0.889848406214
            } 
            print l"\n"$0
        }
        else{print}
       }' file
pattern1 100 200 300
pattern2 266.955 400 400
pattern1 300 900 700
pattern1 200 500 900

Alternatively, use a flag that keeps track of whether the previous line matched pattern1:

$ awk '{if(/pattern2/ && l){$(NF-2)*=0.889848406214} /pattern1/ ? l=1 : l=0;}1;' file
pattern1 100 200 300
pattern2 266.955 400 400
pattern1 300 900 700
pattern1 200 500 900

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.