4

When I run an awk command that has syntax NR== /regex/, it gives unexpected results. The contents of file:

cat file

## This is
## a
## b
## c
## end
## e
## f
## g

Now I add an empty line at start of file.

sed '1 s.^.\n.' file >file2

I add another line like this:

sed '1 s.^.user288752 is back\n.' file2 >file3

Now I run following commands on three files:

awk 'NR== /is/, /end/' file

## This is
## a
## b
## c
## end

awk 'NR== /is/, /end/' file2

In file2 awk matches nothing.

awk 'NR== /is/, /end/' file3

## user288752 is back
## 
## This is
## a
## b
## c
## end

It appears to me that is is matched only if it is present in line 1. But I haven’t writen $0 ~ /is/ in this command. And is is not equal to NR. I know is in this case is regex(/is/) but why is should match NR? What I am missing?

0
12

Let's look at NR == /is/.

This can be rewritten as NR == ( /is/ ), which is two boolean tests:

  1. /is/, which is true if the string is is present in the current record (line).

  2. NR == something, which is true if we're at input line something.

In the awk language, a boolean with a value of true is 1, so if /is/ is true, it will be 1. The expression /is/ will be 1 on each line that contains the string is. The first file that you have has is on the first line, and the second file has is on line 2, and in the third file, you have is on lines 1 and 3.

$ awk '{ printf "NR: %d\t/is/: %d\n", NR, /is/ }' file1
NR: 1   /is/: 1
NR: 2   /is/: 0
NR: 3   /is/: 0
NR: 4   /is/: 0
NR: 5   /is/: 0
NR: 6   /is/: 0
NR: 7   /is/: 0
NR: 8   /is/: 0
$ awk '{ printf "NR: %d\t/is/: %d\n", NR, /is/ }' file2
NR: 1   /is/: 0
NR: 2   /is/: 1
NR: 3   /is/: 0
NR: 4   /is/: 0
NR: 5   /is/: 0
NR: 6   /is/: 0
NR: 7   /is/: 0
NR: 8   /is/: 0
NR: 9   /is/: 0
$ awk '{ printf "NR: %d\t/is/: %d\n", NR, /is/ }' file3
NR: 1   /is/: 1
NR: 2   /is/: 0
NR: 3   /is/: 1
NR: 4   /is/: 0
NR: 5   /is/: 0
NR: 6   /is/: 0
NR: 7   /is/: 0
NR: 8   /is/: 0
NR: 9   /is/: 0
NR: 10  /is/: 0

We now know that /is/ is 1 on certain lines. This means that the NR == /is/ test would be true if /is/ is 1 at the same time as NR is 1, which it can only be on the first line of input, if anywhere, because NR counts lines of input.

Of your three files, the first and last fulfills this criteria, while the second does not.

0

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.