如何使用多模式删除多行,awk pcre2grep sed

How to remove multi-line with multi-pattern, awk pcre2grep sed

我有这个文本文件

tittleofthis123
<Bunlde ver=5.0>
 <Packages>    
  <Package Type="app" FileName="Package_ARM64_beta.msix" Offset="79" Size="5791033">
   <Resources>
    rescode11
   </Resources>
   <b4:Dependencies>
     depcode12
   </b4:Dependencies>
  </Package>
  <Package Type="app" FileName="Package_x64_beta.msix" Offset="580113" Size="7195285">
   <Resources>
    rescode21
    rescode22
   </Resources>
  </Package>
  <Package Type="res" FileName="Package_lang-cy.msix" Offset="579" Size="15">
   <Resources>
    rescode31
   </Resources>
  </Package>
  <Package Type="res" FileName="Package_lang-af.msix" Offset="5791" Size="1578">
   <Resources>
    rescode41
   </Resources>
  </Package>
 </Packages>
</Bundle>

我需要输出为

tittleofthis123
<Bunlde ver=5.0>
 <Packages>    
  <Package Type="app" FileName="Package_x64_beta.msix" Offset="580113" Size="7195285">
   <Resources>
    rescode21
    rescode22
   </Resources>
  </Package>
  <Package Type="res" FileName="Package_lang-af.msix" Offset="5791" Size="1578">
   <Resources>
    rescode41
   </Resources>
  </Package>
 </Packages>
</Bundle>

我试过了this

pcre2grep -M -v 'ARM64.*(\n|.)*</Package>|lang-cy.*(\n|.)*</Package>' 123.txt

但是当然结果不对,因为所有的包都是一样的</Package>,所以不是只过滤ARM64,而是过滤掉所有到底部的包。而且我有更多的包要排除,所以我可能不应该使用 -v inverse,但不知道如何保留 Title, <Bundle>, and <Packages>

尝试过this and this

awk '/ARM64/,/<\/Package>/ {next} {print}' 123.txt

实际上效果很好。但我不明白如何让它过滤多个包,如 '/ARM64/,/<\/Package>//lang-cy/,/<\/Package>/。同样,我需要排除很多包,所以也许不做 {next} 事情,仍然不知道如何保留 Title, <Bundle>, and <Packages>

我认为this非常接近我需要的

sed -n '/<Package/{:a;N;/\n*<\/Package>/!ba; /x64/p}' 123.txt

也很好用,但我还是很无能,不知道怎么加入x64lang-af这样的滤镜。 Title, <Bundle>, and <Packages>

也一样

其实this也是差不多的情况,但是我完全看不懂

awk '/ARM64/,/<\/Package>/ {next} {print}' 123.txt

It actually works well. But I don't understand how to make it filter more than one Package like '/ARM64/,/<\/Package>/ and /lang-cy/,/<\/Package>/

由于两个结束条件相等,您可以使用 ||(替代)来构建开始条件,触发 ARM64lang-cy 的方式如下

awk '/ARM64/||/lang-cy/,/<\/Package>/ {next} {print}' 123.txt

并再次使用 || 来获得另一个排除项,例如也删除 lang-af 你可能会做的

awk '/ARM64/||/lang-cy/||/lang-af/,/<\/Package>/ {next} {print}' 123.txt

等等。

警告:你所拥有的似乎类似于 XML,请注意 GNU AWK 最适合与可能的实体一起使用使用正则表达式来描述。如果你的,不能用这些来描述,就像 XML 的情况一样,那么你需要工具来处理 Chomsky Type-2 装置,而不是严格意义上的正则表达式。

这可能适合您 (GNU sed):

sed '/<Package Type/{:a;N;/<\/Package>/!ba;/_x64_\|_lang-af/!d}' file

收集 <Package Type</Package> 之间的行,如果它包含 _x64__lang-af,请不要删除该集合。