awk在匹配后首次出现

时间:2015-06-04 17:57:45

标签: bash awk sed

我正在尝试在两个模式之间打印文本文件的一部分,然后仅返回第一个匹配项。应该很简单,但我似乎无法找到解决方案。

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>")
}

打印所有匹配项:

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

我需要它只返回第一个,即:

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

谢谢!

5 个答案:

答案 0 :(得分:8)

永远不要使用范围表达式,因为它们使得琐碎的工作变得非常简单,但是需要完全重写或重复条件才能完成更有趣的任务。始终使用旗帜:

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

答案 1 :(得分:2)

在某种程度上添加了Ed Morton的答案,你可以再次编写它来处理一些嵌套的if条件或if语句中是否还有其他一对括号(例如for for for for循环)。

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

输出:

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>")
}

是:

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

count将继续计算起始大括号的数量,并将打印语句,直到计数再次达到0。

我的输入可能与问题不同,但信息可能有用。

答案 2 :(得分:1)

你可以,

Person

打印第一场比赛后退出

答案 3 :(得分:1)

我认为if块中没有}

使用GNU sed:

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

以下是它的工作原理:

/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
}

答案 4 :(得分:1)

sed '/Option_1/,/}/ !d;/}/q' YourFile
  • 删除分隔符内的所有内容,并在最后一行后退出(仅限1节)
  • 对于非GNU sed,请将;替换为d一个真正的新行