Awk prints the first occurrence after the match

I am trying to print a portion of a text file between two patterns and then only return 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>")
}

      

Will print all matches:

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

      

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

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

      

Thank!

+3


source to share


5 answers


Never use range expressions, as they make trivial tasks very trivial, but then require complete rewriting or duplication of conditions for even 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>")
}

      

+8


source


Adding somewhat to Ed Morton's answer, you can rewrite it to work for some nested if condition, or if there are other pairs of curly braces in the if statement (like the parentheses for a 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 an:

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

      

count

will count the number of starting curly braces and print the expression until the counter reaches 0 again.

My input may be different from the question, but the information may be helpful.

+2


source


You can do,

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

      

This will exit after printing the first match

+1


source


I assumed there are no if blocks inside }

.

Using GNU Command:

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

      

This is 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
}

      

+1


source


sed '/Option_1/,/}/ !d;/}/q' YourFile

      

  • remove anything not inside your separator and close it after the last line (so only 1 section)
  • for non-GNU sed, replace ;

    after d

    with a newline
+1


source







All Articles