存在字符串时如何在两个定界符之间提取文本

how to extract text between two delimiters when string is present

我有一个大数据文件,如下所示:

//
ID   1.1.1.258
DE   6-hydroxyhexanoate dehydrogenase.
CA   6-hydroxyhexanoate + NAD(+) = 6-oxohexanoate + NADH.
CC   -!- Involved in the cyclohexanol degradation pathway in Acinetobacter
CC       NCIB 9871.
//
ID   1.1.1.259
DE   3-hydroxypimeloyl-CoA dehydrogenase.
CA   3-hydroxypimeloyl-CoA + NAD(+) = 3-oxopimeloyl-CoA + NADH.
CC   -!- Involved in the anaerobic pathway of benzoate degradation in
CC       bacteria.
//
ID   1.1.1.260
DE   Sulcatone reductase.
CA   Sulcatol + NAD(+) = sulcatone + NADH.
CC   -!- Studies on the effects of growth-stage and nutrient supply on the
CC       stereochemistry of sulcatone reduction in Clostridia pasteurianum,
CC       C.tyrobutyricum and Lactobacillus brevis suggest that there may be at
CC       least two sulcatone reductases with different stereospecificities.
//

我想提取此文件中包含作品 anaerobic 的部分。我特别想要 ID 行。

有没有办法在 ID 和 // 之间搜索文件以找到 anaerobic 并将输出打印到新文件?如果打印了整个部分,那很好,我可以在之后将其 grep 出来。

预计应该是

ID   1.1.1.259

ID   1.1.1.259
DE   3-hydroxypimeloyl-CoA dehydrogenase.
CA   3-hydroxypimeloyl-CoA + NAD(+) = 3-oxopimeloyl-CoA + NADH.
CC   -!- Involved in the anaerobic pathway of benzoate degradation in
CC       bacteria.
//

tac file | sed -n '/anaerobic/,$p' | sed -n '/^ID/ {p;q}'

  • tac **file**: 从头到尾打印文件
  • sed -n '/anaerobic/,$p': 从第一次出现 anaerobic 到文件末尾打印
  • sed -n '/^ID/ {p;q}':搜索以ID开头的行, 仅打印第一次出现

使用 awk 很简单

awk '/anaerobic/' RS='//\n' ORS='\n//' ./file.txt

为了多样化,可能的GNU sed解决方案:

sed -nr ':a; \@(^|\n)//$@! { N; ba }; /anaerobic/p' data

  • -n => 禁止自动打印图案 space
  • -r => 扩展正则表达式
  • :a => 标签定义
  • ba => 跳转到标签 a
  • N => 将下一行附加到模式 space
  • \@(^|\n)//$@! => 匹配不以 //
  • 结尾的 "sections"

\@(^|\n)//$@! { N; ba } 因此将下一行附加到模式 spaces 直到它找到 // 部分分隔符。 /anaerobic/p 然后检查当前部分是否包含 anaerobic,如果包含,p 命令打印它。