suegene
suegene

Reputation: 295

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

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

Upvotes: 9

Views: 11681

Answers (2)

Levon
Levon

Reputation: 143152

This script will do what you like:

{
  if ($2 < prev_count)
    $2 = prev_count
  else
    prev_count = $2

  printf("%d   %d\n", $1, $2)
}

This is a verbose version to be easily readable :)

Upvotes: 2

William Pursell
William Pursell

Reputation: 212634

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

Upvotes: 8

Related Questions