Say one of your data files returns you all their readings. After removing all the clutter; you obtain, with always 3 columns:
-ERROR -1.57 -2.02
-2.10 -0.57 ERROR
-4.70 ERROR -0.52
-2.20 ERROR -0.02
-2.20 -0.07 ERROR
I know ERROR
is the only error message and happens for any data at random, and is, therefore, the only value that isn't a number.
THE CHALLENGE
How can I replace any invalid reading with the last successful one? I've tried
awk -F' ' ' {if (isNumber $1){ replace with previous $1}}' < log.data
But how do you reference the previous reading to begin with?
Expected output:
0 -1.57 -2.02
-2.10 -0.57 -2.02
-4.70 -0.57 -0.52
-2.20 -0.57 -0.02
-2.20 -0.07 -0.02
CodePudding user response:
Assumptions:
- all rows have the same number of space-delimted fields/columns
- all non-numeric values contain the literal string
ERROR
- if first row contains a non-numeric value then the replacement value will be zero (0)
One awk
idea:
awk '
{ for (i=1;i<=NF;i ) { # loop through fields
if ($i ~ "ERROR") # if problematic value found then ...
$i=last[i] 0 # replace with the last value seen; " 0" to force undefined to be zero (and not "")
last[i]=$i # save current field as "last" for the next input line
}
print $0 # print current line
}
' log.data
This generates:
0 -1.57 -2.02
-2.10 -0.57 -2.02
-4.70 -0.57 -0.52
-2.20 -0.57 -0.02
-2.20 -0.07 -0.02
CodePudding user response:
You may use this awk
:
awk '{
for (i=1; i<=NF; i) {
if ($i 0 != $i)
$i = prev[i] 0
prev[i]=$i
}
} 1' file
0 -1.57 -2.02
-2.10 -0.57 -2.02
-4.70 -0.57 -0.52
-2.20 -0.57 -0.02
-2.20 -0.07 -0.02
$i 0 != $i
will return true if $i
is non-numeric value.