按模式拆分文件,仅保留包含第二个模式的片段

按模式拆分文件,仅保留包含第二个模式的片段

我在之前的答案中找到了以下 awk 脚本,用于根据模式将大文件拆分为较小的部分(用不同的模式替换“标题行”)。然而,我需要更进一步,因为可能会创建数百万个零件,但如果我可以再次过滤每个零件,它将得到我需要的东西。

awk '
    /header-line/ {++part}
    {print >sprintf("part-%03d.txt", part)}
'

是否可以在写入每个“部分”之前或之后询问该部分,以检查该部分中是否存在某种模式,并且仅在与附加模式匹配时将该部分写出。

例如,初始条件为“ID:”(上面的标题行)。然后我想搜索为特定方法名称创建的每个“部分”;将其称为“searchForThisMethod”作为要搜索的字符串,该字符串可能位于零件中的各个位置。

输入示例:

ID: 1
bb
bb
bb
bb
secondaryCheck
ID: 2
b
b
b
b
b
b
b
b
ID: 3
h
h
h
h
h
secondaryCheck
g
g
g
g

答案1

您可以拆分文件,然后grep -q some_method在每个部分上运行并删除它,如果错误的例如

for file in part-*.txt; do
grep -q some_method "$file"
  if [ $? -ne 0 ]
    then
      rm "$file"
  fi
done


使用两遍 - 从输入中删除包含的“部分”,some_method然后分割结果,例如用于sed第一遍和awk第二遍的代码:

sed -e '1{h;d;}' -e '/ID/!{H;$!d;}' -e 'x;/some_method/!d' infile | \
awk '/ID/{++part}{print > sprintf("part-%03d.txt", part)}'

sed将第一行复制到h旧缓冲区上并删除它,然后附加与旧缓冲区d不匹配的每一行,如果不是最后一行则将其删除,并且 e更改匹配的行上的缓冲区,如果不包含则删除模式空间。然后结果通过管道传输到.如果出现错误,则必须使用以下文件:IDHxIDsome_methodawktoo many open filesclose()

sed -e '1{h;d;}' -e '/ID/!{H;$!d;}' -e 'x;/some_method/!d' infile | \
awk '/ID/{++part}{close(fn);fn=sprintf("part-%03d.txt", part);print >> fn}'

或者,如果你在gnu/anything 上,你可以使用csplit而不是awk

sed '1{h;d};/ID/!{H;$!d};x;/some_method/!d' infile | \
csplit -f 'part-' -b '%03d.txt' -sz - /ID/ '{*}'

相关内容