awk solution for comparing current line to next line and printing one of the lines based on a condition

suegene picture suegene · Jul 28, 2012 · Viewed 11.3k times · Source

I have an input file that looks like this (first column is a location number and the second is a count that should increase over time):

1       0
1       2
1       6
1       7
1       7
1       8
1       7
1       7
1       9
1       9
1       10
1       10
1       9
1       10
1       10
1       10
1       10
1       10
1       10
1       9
1       10
1       10
1       10
1       10
1       10
1       10

and I'd like to fix it look like this (substitute counts that decreased with the previous count):

1       0
1       2
1       6
1       7
1       7
1       8
1       8
1       8
1       9
1       9
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10
1       10

I've been trying to use awk for this, but am stumbling with getline since I can't seem to figure out how to reset the line number (NR?) so it'll read each line and it's next line, not two lines at a time. This is the code I have so far, any ideas?

awk '{a=$1; b=$2; getline; c=$1; d=$2; if (a==c && b<=d) print a"\t"b; else print c"\t"d}' original.txt > fixed.txt

Also, this is the output I'm currently getting:

1       0
1       6
1       7
1       7
1       9
1       10
1       9
1       10
1       10
1       9
1       10
1       10
1       10

Answer

William Pursell picture William Pursell · Jul 28, 2012

Perhaps all you want is:

awk '$2 < p { $2 = p } { p = $2 } 1' input-file

This will fail on the first line if the value in the second column is negative, so do:

awk 'NR > 1 && $2 < p ...'

This simply sets the second column to the previous value if the current value is less, then stores the current value in the variable p, then prints the line.

Note that this also slightly modifies the spacing of the output on lines that change. If your input is tab-separated, you might want to do:

awk 'NR > 1 && $2 < p { $2 = p } { p = $2 } 1' OFS=\\t input-file