在 Unix 中的文件中搜索包含换行符/换行符/换行符的字符串

在 Unix 中的文件中搜索包含换行符/换行符/换行符的字符串

我正在文件中搜索字符串(字符串包括新行/换行符)并在模式匹配后打印 2 行,例如文件包含:-(已编辑)

           <cfu>
              <statm1>
              <status>good</status>
           </cfu>
           <cfu>
              <statm2>
              <status>not found</status>
           </cfu>
           <cfu>
              <statm3>
              <status>empty</status>
           </cfu>
           <cfa>
              <statm1>
              <status>good</status>
           </cfa>
           <cfa>
              <statm2>
              <status>not found</status>
           </cfa>
           <cfa>
              <statm3>
              <status>empty</status>
           </cfa>
              
           

我试过像

awk -v RS=""'/<cfu> <statm1/{i=NR+2}(NR<=i){print}' file_name

但没有运气,请帮忙

预期输出:-

           <cfu>
              <statm1>
              <status>good</status>
           </cfu>

答案1

无需尝试解码 XML(无论如何,输入看起来并不完全像 XML),使用 的pcregrepultilineM模式:

$ pcregrep -Mo '(?s)<cfu>(?:(?!</cfu>).)*<statm1>.*?</cfu>' your-file
<cfu>
              <statm1>
              <status>good</status>
           </cfu>
  • (?s)打开s导致.也匹配换行符的标志。
  • (?!</cfu>)..是不是 开头的任意字符 ( ) </cfu>。我们用 匹配 0 个或多个*。我们用它来代替 来.*确保我们不会超过下一个结束时间</cfu>
  • *?是 的非贪婪版本*

如果您只想要该<status>值:

$ pcregrep -Mo1 '(?s)<cfu>(?=(?2)*<status>([^<]*))((?!</cfu>).)*<statm1>.*?</cfu>' your-file
good

答案2

使用正确的 HTML/XML 解析器,在用root节点包围文件后:

xidel

xidel --output-node-format=xml -e '//cfu[contains(., "good")]' file

输出:

<cfu>
          <statm1>
          <status>good
       </status></statm1></cfu>

xmlstarlet

xmlstarlet format -H file | sponge file
xmlstarlet sel -t -c '//cfu[contains(., "good")]' file 2>/dev/null

输出:

<cfu>
          <statm1>
          <status>good
       </status></statm1></cfu>

相关内容