1

I have a text file called junk.txt:

hello
foo
0
-1
0
1
0
2
0
foo

Cindy
00000

Lou
2 000
0
Who
0000
0
wat?
0000 00000
0
0
0000 00000

filler

00

0
00
000
0000
0

0
bye

When I run the following I get this:

cat junk.txt | awk '{if (/foo/ ~ $1) print $1,"<-- found match"; else print $1}'
awk: cmd. line:1: warning: regular expression on left of `~' or `!~' operator
hello
foo
0 <-- found match
-1
0 <-- found match
1
0 <-- found match
2
0 <-- found match
foo
 <-- found match
Cindy
00000
 <-- found match
Lou
2
0 <-- found match
Who
0000
0
wat?
0000
0
0
0000
 <-- found match
filler
 <-- found match
00
 <-- found match
0 <-- found match
00 <-- found match
000 <-- found match
0000 <-- found match
0 <-- found match
 <-- found match
0 <-- found match
bye

I understand what is happening when the regex is to the left of the ~.

I understand that a 0 or an empty string (null?) will count as a match.

What I do not understand is why sometimes a 0 will match, and sometimes it won't. It seems like it has something to do with whatever record was processed before it, but I thought awk treated each input record independently so they shouldn't affect one another (at least not without some variable assignments or other manipulation).

EDIT: In case it matters I'm using GNU Awk 4.1.3

4

From (g)awks man page:

~ !~        Regular expression match, negated match.  NOTE: Do not use a constant regular  expression  (/foo/)
            on  the left-hand side of a ~ or !~.  Only use one on the right-hand side.  The expression /foo/ ~
            exp has the same meaning as (($0 ~ /foo/) ~ exp).  This is usually not what you want.

What do you expect to happen if you use it in a way it explicitly tells you not to?

  • As I said, I understand what is happening when you have a regex to the left of a ~. I read the man page. What I don't understand, and what my question was was why is it inconsistent. Sometimes a 0 will match, sometimes it will not. Sometimes 0000 will match, sometimes it won't. Why? – Linoob Jun 30 '16 at 15:37
3

Actually, that's an interesting question. @tink pointed out why your code does not work as expected, but that wasn't the question. The question was "why does 0 sometimes match".

If (/foo/ ~ $1) really means (($0 ~ /foo/) ~ $1), then ($0 ~ /foo/) will evaluate to 1 if the line contains foo and 0 otherwise. Thus, you are (mostly) evaluating 0 ~ $1. If the input line is empty, then $1 == "", and an empty regular expression always matches. If the input line is exactly 0, so is $1, and 0 ~ 0 is true. If the input line is 000, for example, then so is $1, and 0 ~ 000 should not be true. However, it is likely that the 000 is converted to 0 before the match is checked.

But unfortunately, this explanation does not cover all cases.

Case 1

0 <-- found match
a
0 <-- found match
0 <-- found match

This is exactly as expected.

Case 2

0 <-- found match
00 00 <-- found match
0 <-- found match

This is also what is expected, provided that any number of zeros is interpreted as 0. But now, this:

Case 3

0 <-- found match
a
00 0
0

This can not be explained away so simply. After a failed match, the conversion to zero does not seem to happen, and following lines that should match don't.

Case 4

0 <-- found match
a
00 00
a
0 <-- found match

Whatever happens, another failed match seems to reset awk's behaviour to normal, and matching works as expected again.

To conclude, either the explanation from the GNU awk man page, which is not part of the info page, incidentally, is incorrect (or, at the very least, incomplete), or the program contains a bug.

  • "If the input line is 000, for example, then so is $1, and 0 ~ 000 is not true." Then why does it match? 000 <-- found match – Linoob Jun 30 '16 at 15:34
  • @Linoob You are correct. I have amended my answer. – Michael Vehrs Jul 1 '16 at 7:35
  • Thanks for taking another look at it. Seems like a bug to me, but since this isn't a normal use case I'm not going to worry about it. I was just trying to understand awk a bit better. – Linoob Jul 5 '16 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.