0

I have to print the next line if the previous line matches a condition.

file a.dat with below contents

1
2
3
1
2
1

if $1 matches 3 then print 1(next line). I tried it with below awk statement

awk ' { if($1=="3") { {next} {print $1} } }' a.dat

but it didn't work. When i was looking for it i understood that when awk encounters a next no further rules are executed for the current record, hence i got an empty result. Is there a way to get around this with next itself using awk.

Lee Duhem
  • 14,695
  • 3
  • 29
  • 47
Vignesh I
  • 2,211
  • 2
  • 20
  • 40
  • possible duplicate of [printing with sed or awk a line following a matching pattern](http://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern) – αғsнιη Dec 18 '14 at 18:56

3 Answers3

2
awk '/bbbbb/{a=1;next}a{print;a=0}' File

Pattern being searched for is bbbbb. If pattern found, set variable a to 1. Goto next record. If a is 1, print the record and unset a. This will print the next line for all the lines matching the pattern.

Sample:

AMD$ cat File
aaaaa
bbbbb
ccccc
ddddd
eeeee
aaaaa
bbbbb
ccccc
ddddd
eeeee
AMD$ awk '/bbbbb/{a=1;next}a{print;a=0}' File
ccccc
ccccc
Arjun Mathew Dan
  • 5,240
  • 1
  • 16
  • 27
2

It's not clear when you say "matches 3" if you mean contains 3 or is numerically equal to 3 or is string equal to 3 or something else or if you want to print every line that follows a 3 or just the first or if you want to print a line containing 3 if the previous line was 3 or skip until you reach a non-3 but the general approach would be based on:

awk 'f{print; f=0} $0==3{f=1}' file

or even:

awk 'f&&f--; $0==3{f=1}' file

The variable f is commonly used to mean found. See https://stackoverflow.com/a/17914105/1745001 for how to generally print lines after matches with awk.

Community
  • 1
  • 1
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • and I thought `f` was for `flag` `:P` – jaypal singh Dec 18 '14 at 06:25
  • 3 is numeric and i would like to print the next line.. awk 'f{print; f=0} $0==3{f=1}' file was the one i was looking for.. thanks.. :) – Vignesh I Dec 18 '14 at 10:14
  • 1
    @jaypalsingh no, a flag is what it is, not what it means. Down that path would lie `v` for `variable`, though I'm as guilty as anyone else of using `a` for `array` but for some reason my sensibilities don't scream over that one as long as it's glaringly obvious what it's being used for in a tiny script :-). – Ed Morton Dec 18 '14 at 14:19
0

This will print the next line if pattern is true:

awk '_-->0;$1==3{_=1}' file
4

some more readable..

awk 'f-->0;$1==3{f=1}' file

or as Ed suggested.

awk 'f&&f--;$1==3{f=1}' file

Another variation

awk '/^3$/{f=1;next} f-->0' file
Jotne
  • 40,548
  • 12
  • 51
  • 55
  • 1
    I strongly suspect that naming a variable `_` has a significant negative impact on the readability. Why would you do that? It's arguably the second-worst possible choice of variable name, right behind naming the variable with double negatives (`not_un_found=1`). I also wouldn't use an unguarded `f-->0` in case the input file is so huge that the variable value wraps back around to positive - hence the `f&&f--` guard to stop decrementing at zero. – Ed Morton Dec 18 '14 at 15:14
  • 1
    @EdMorton It was was just for fun. Fixed it. – Jotne Dec 18 '14 at 16:11
  • Sounds good, we don't want anyone confusing awk with the p-word ;-). – Ed Morton Dec 18 '14 at 16:50