Conditional awk command printing the 'else' statement only once

Apologies for the confusing title. I'd like to process columnar files using a conditional awk statement. Basically, if the number 27606 is found in column 2, I want to print length($4)-length($5), otherwise I want to print "0" once if 27606 is not found in column 2.

Consider present.txt:

First   11111   Third   ABCDE   A
First   27606   Third   ABCDE   A
First   22222   Third   ABCDE   A
First   33333   Third   ABCDE   A
First   44444   Third   ABCDE   A

and absent.txt:

First   11111   Third   ABCDE   A
First   55555   Third   ABCDE   A
First   22222   Third   ABCDE   A
First   33333   Third   ABCDE   A
First   44444   Third   ABCDE   A

For present.txt, the output should simply be: 4. For absent.txt, the output should simply be: 0.

I've tried the following:

awk '{if ($2 ~ /27606/){print length($4)-length($5)} else { print "0" }}' file

This 'works' in the way I want by printing '4' for present.txt, however it prints 0 for every line that doesn't have 27606 in column 2 in absent.txt... Output:

0
0
0
0
0

I've also tried:

awk '$2 ~ /27606/ {found=1} END {if (!found) print "0"} {if (found) print length($4)-length($5)}' file

This works with absent.txt: "0" is only printed once. However, for present.txt, length($4)-length($5) is printed for the first line matching 27606 in column $2 as well as every subsequent line. Output:

4
4
4
4

What command can I use so that the output from present.txt is '4', and the output from absent.txt is '0'? Thanks!

Upvotes: 2

Views: 1012

Answers (2)

Ed Morton
Ed Morton

Reputation: 203209

It sounds like 27606 can only occur on 1 line max so all you'd need is:

$ awk '$2==27606{diff=length($4)-length($5); exit} END{print diff+0}' present.txt
4

$ awk '$2==27606{diff=length($4)-length($5); exit} END{print diff+0}' absent.txt
0

Upvotes: 1

Shawn
Shawn

Reputation: 52334

When the value is found, print out your calculated value and increment a counter. In an END block print 0 if the counter is 0:

awk '$2 == 27606 { print length($4) - length($5); found++ }
     END { if (!found) print 0 }' input.txt

If you want to only output one number even if the value is found multiple times:

awk '$2 == 27606 && !found { print length($4) - length($5); found++ }
     END { if (!found) print 0 }' input.txt

Upvotes: 3

Related Questions