0

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

3

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.

  • After trying that, it just outputs the entire file now (not restricting to /word/ or lines 7-13, however, once it hits line 7, it will print a line that contains /word/ for every line until after line 13). I've added an edit to show you what I mean – SheepWaffle Oct 30 '18 at 1:34
  • you've got the logic exactly as above, with && between the three pieces? – Jeff Schaller Oct 30 '18 at 1:35
  • Correct, see my edit I have posted. – SheepWaffle Oct 30 '18 at 1:41
  • did the print end up on a separate line, or is that just wrapping? – Jeff Schaller Oct 30 '18 at 1:42
  • Ah that was it. Sorry, dumb mistake of wanting to have my prints on another line to clean it up. With everything on one line it works now, thanks! that's probably what was giving me trouble on my other attempts with this too! – SheepWaffle Oct 30 '18 at 1:45
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

How about

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