Ian Gooch
Ian Gooch

Reputation: 53

awk read conditions on one row, print the output of another row

I have a small issue with awk and I can't find the solution.

I would like to swap the NR == in the syntax so I read the conditions of NR ==4 and output NR ==3.

awk -F 'NR ==4 { if ($1 < $2 && NF ==4) print $2 "," $4;
                 if ($1 < $2 && NF ==3) print $2 "," "--";
                 if ($1 > $2 && NF ==4) print $1 "," $3;
                 if ($1 > $2 && NF ==3) print $1 "," "--";
               }' infile > outfile

What I would like is the above (reads NR ==4 but outputs NR ==3)

awk -F 'NR ==4 { if ($1 < $2 && NF ==4) NR ==3 print $2 "," $4;
        NR ==4   if ($1 < $2 && NF ==3) NR ==3 print $2 "," "--";
        NR ==4   if ($1 > $2 && NF ==4) NR ==3 print $1 "," $3;
        NR ==4   if ($1 > $2 && NF ==3) NR ==3 print $1 "," "--";
               }' infile > outfile

infile:

05:45,11:55,17:37,09:59
0.2,2.3,0.4,2.6
06:18,12:28,18:15
2.3,2.2,0.6

desired outfile for this condition where NR==4 $1>$2 && NF==3:

12:28, --:--

Upvotes: 0

Views: 310

Answers (1)

mklement0
mklement0

Reputation: 440092

I'm not entirely clear on what you want and your sample output seems inconsistent with your awk program, but perhaps this will get you started:

    awk 'BEGIN{FS=OFS=","}
         NR==3 { 
            split($0, line3fields);
            getline;
            if ($1 < $2 && NF==4) print line3fields[2], line3fields[4]
            if ($1 < $2 && NF==3) print line3fields[2], "--:--"
            if ($1 > $2 && NF==4) print line3fields[1], line3fields[3]
            if ($1 > $2 && NF==3) print line3fields[1], "--:--"
         }
         ' infile > outfile
  • BEGIN block: Since your input and output are ,-separated, sets both the input (FS) and output (OFS) field separators to ,.
  • Next, line 3 is processed: its fields - via function split() - are stored in array variable line3fields for later use.
  • getline line then reads the next line - line 4 in this case - into $0, and its tokens into $1, $2, ...
  • The if statement therefore operates on line 4's fields, whereas the print statement references line 3's tokens via array line3fields.

As for your original code:

Once you've selected a matching line with pattern NR==4, the associated action (block) will only be processed for that line; therefore, inside your block, you can't refer directly to other lines with conditions such as NR==3.

Your options are:

  • Use getline to read subsequent line(s), as in my code above.
  • Use separate pattern-action pairs (e.g., one for NR==3 and another for NR==4, and store lines of interest in variables for use in a later action).

Upvotes: 2

Related Questions