Bash 匹配后首次出现的awk打印

Bash 匹配后首次出现的awk打印,bash,awk,sed,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&

我试图在两种模式之间打印文本文件的一部分,然后只返回第一个匹配项。应该很简单,但我似乎找不到解决办法

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>")
}
我需要它只返回第一个,即:

if (var == "Option_1"){
  document.write("<td>head1</td>")
  document.write("<td>text1</td>")
}
if(var==“选项1”){
文件。编写(“标题1”)
文件。写入(“文本1”)
}
谢谢

你能做到

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

这在打印第一个匹配后退出

我假设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
}

永远不要使用范围表达式,因为它们会使琐碎的工作变得非常简单,但对于更有趣的任务,则需要完全重写或复制条件。始终使用标志:

$ awk '/Option_1/{f=1} f{print; if (/}/) exit}' file
if (var == "Option_1"){
  document.write("<td>head1</td>")
  document.write("<td>text1</td>")
}
$awk'/Option_1/{f=1}f{print;if(/}/)exit}文件
如果(var==“选项1”){
文件。编写(“标题1”)
文件。写入(“文本1”)
}

在Ed Morton的答案中添加了一些内容,您可以再次编写它来处理某些嵌套的if条件,或者如果if语句中存在任何其他大括号(例如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>")
}
if(var==“选项1”){
文件。编写(“标题1”)
如果(条件){
//代码
}
文件。写入(“文本1”)
}
如果(var==“选项2”){
文件。编写(“标题2”)
文件。写入(“文本2”)
}
如果(var==“选项1”){
文件编写(“标题3”)
文件。写入(“文本3”)
}
是:

if(var==“选项1”){
文件。编写(“标题1”)
如果(条件){
//代码
}
文件。写入(“文本1”)
}
count
将对开始大括号的数量进行计数,并将打印语句,直到计数再次达到0为止

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

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

是的,我试过了。。。但它只返回第一次出现的第一行。不过谢谢。对不起,我修改了。再试一次,就这样。谢谢你的钱!如果在示例文件中搜索
选项2
,则此操作将不起作用。请注意,您必须复制结束条件
/}/
。永远不要使用范围表达式。我不知道我们可以简单地使用
if(/pattern/)
好东西。谢谢Ed.@anishsane-yes
/foo/
$0~/foo/
的简写,无论您在条件上下文中使用它。更简单:
/Option_1/{:a;p;/}/q;Nba}
您需要-n选项,否则如果您搜索选项,所有其他行都将被打印出来。哈哈,是的,我犯了与您尝试简化我的答案相同的错误:)谢谢您混淆了awk和shell语法。在awk
((count+=1))
中,算术运算不需要成对的paren,一个简单的
count++
就可以了。除了第一个块之外,您的脚本将失败,请尝试
/Option\u 2/
。感谢@EdMorton发现我的错误。我已经更新了我的答案,现在它似乎适用于任何选项。
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>")
}
sed '/Option_1/,/}/ !d;/}/q' YourFile