syntax
syntax

Reputation: 203

awk print first occurrence after match

I'm trying to print a portion of a text file between two patterns, then return only the first occurrence. Should be simple but I can't seem to find a solution.

cat test.html

if (var == "Option_1"){
  document.write("<td>head1</td>")
  document.write("<td>text1</td>")
}
if (var == "Option_2"){
  document.write("<td>head2</td>")
  document.write("<td>text2</td>")
}
if (var == "Option_1"){
  document.write("<td>head3</td>")
  document.write("<td>text3</td>")
}

This prints all matches:

awk '/Option_1/,/}/' test.txt

I need it to return only the first, i.e.:

if (var == "Option_1"){
  document.write("<td>head1</td>")
  document.write("<td>text1</td>")
}

Thanks!

Upvotes: 3

Views: 6486

Answers (5)

NeronLeVelu
NeronLeVelu

Reputation: 10039

sed '/Option_1/,/}/ !d;/}/q' YourFile
  • delete everything not inside your delimiter and quit after last line of it (so 1 section only)
  • for non GNU sed, replace the ; after d by a real new line

Upvotes: 2

Rakholiya Jenish
Rakholiya Jenish

Reputation: 3223

Adding somewhat to Ed Morton's answer, you can write it again to work for some nested if condition or if there exist any other pair of braces inside the if statement (eg. braces for for loop).

awk '/Option_1/{f=1} f{ if(/{/){count++}; print; if(/}/){count--; if(count==0) exit}}' filename

output for:

if (var == "Option_1"){
  document.write("<td>head1</td>")
  if (condition){
    //code
  }
  document.write("<td>text1</td>")
}
if (var == "Option_2"){
  document.write("<td>head2</td>")
  document.write("<td>text2</td>")
}
if (var == "Option_1"){
  document.write("<td>head3</td>")
  document.write("<td>text3</td>")
}

is:

if (var == "Option_1"){
  document.write("<td>head1</td>")
  if (condition){
    //code
  }
  document.write("<td>text1</td>")
}

count will keep count on number of starting braces and will print the statement until the count reaches 0 again.

My input might be different from question but the information may be useful.

Upvotes: 2

Alfwed
Alfwed

Reputation: 3282

I assumed that there are no } inside the if blocks.

Using GNU sed :

sed -n '/Option_1/{:a N;s/}/}/;Ta;p;q}' file

Here's how it works :

/Option_1/{     #search for Option_1
    :a          #create label a
    N;          #append next line to pattern space
    s/}/}/;     #substitute } with }
    Ta;         #if substitution failed, jump to label a
    p;          #print pattern space
    q           #exit
}

Upvotes: 2

bkmoney
bkmoney

Reputation: 1256

You can do,

awk '/Option_1/,/}/{print; if ($0 ~ /}/) exit}' test.txt

This exits after printing the first match

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203522

Never use range expressions as they make trivial jobs very slightly briefer but then require a complete rewrite or duplicate conditions for even slightly more interesting tasks. Always use a flag:

$ awk '/Option_1/{f=1} f{print; if (/}/) exit}' file
if (var == "Option_1"){
  document.write("<td>head1</td>")
  document.write("<td>text1</td>")
}

Upvotes: 9

Related Questions