1

I am trying to write a script (.awk) that will print out lines that contain a certain string between lines 7-13. I have it partially working however it prints out all lines that contain the string rather than only between 7-13.

#!/usr/bin/awk -f
BEGIN { (NR>=7) && (NR<=13) }
/word/ {print $0}

the output when running

script.awk filename

is all lines that contain the word

edit:

After trying out what jeff suggested, I get this with his suggestion. /needle/ being the keyword.

Code Code Solved!

The issue was that I had {print $0} on another line, used to it in other languages where I like to separate my code out

1

3 Answers 3

5

You've put the line restriction logic in the "BEGIN" block, which is executed before awk reads in any data. Move that logic to the main loop:

NR >= 7 && NR <= 13 && /word/ { print }

$0 is the default print argument, if none is given... or, even shorter as

NR >= 7 && NR <= 13 && /word/

since {print} is the default action, if none is specified.
The main body of an awk script is of the form "pattern" "action"; you want the pattern to prefix the action that you want. Here, the pattern requires the three tests to be true, and the action to be to print the line. Putting the print on a separate line means that there's no "action" when "passing" the tests, and there's no "pattern" for printing every line -- resulting in every line being printed.

0
2

Just complementing Jeff's answer with one written in sed:

sed -n '7,13 { /expression/ p; }' <file

This would print every line between lines 7 and 13 (inclusively) that matches the regular expression expression. The default output is turned off with -n so only the lines explicitly printed with the p command will be outputted.

A direct translation of the above sed script into awk:

awk 'NR == 7, NR == 13 { if (/expression/) print }' <file

The condition NR == 7, NR == 13 should be read as "from any input record for which NR is 7, to any input record for which NR is 13", where "input record" by default is a line and NR is the number of records (lines) read so far.

0
0

How about

awk 'NR>6&&NR<14&&/word/' file
2
  • 3
    This is essentially Jeff's answer with the <= and >= replaced by < and > and the line numbers adjusted accordingly.
    – Kusalananda
    Oct 30, 2018 at 21:08
  • 1
    Yep, 2 bytes saved, bonus :-)
    – steve
    Oct 30, 2018 at 21:09

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.