只有当它们在一系列文件中一个接一个地出现时,有没有办法提取两个连续的记录?

Is there a way to pull out two successive records only if they occur one after the other in a series of files?

我正在尝试提取两个连续的记录,但前提是这些记录一个接一个地出现。我正在处理看起来像这样的文件:

#File1
>CHB001 PatternA
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
>CHB002 PatternB
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
LETTERSRANDOMSTRINGHH
>CHB002 PatternC
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH

#File2
>CHB0022 PatternA
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
>CHB0023 PatternC
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
>CHB0024 PatternB
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
LETTERSRANDOMSTRINGHH

我想从所有文件中提取 PatternA 和 PatternB 下的所有内容,但前提是它们一个接一个地出现。我想要的输出是:

>CHB001 PatternA
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
>CHB002 PatternB
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
LETTERSRANDOMSTRINGHH

我试过:

awk -v RS='>' -v ORS='>' '/PatternA/,/PatternB/' file*.txt > output.txt

但这会在输出中包含文件 2 中的 PatternC,我想跳过文件 2,因为 PatternA 和 PatternB 不会连续出现。接下来我尝试了这个命令:

awk -v RS='>' -v ORS='>' '/PatternA/{l=NR}/PatternB/&&NR==l+1' file*.txt > output.txt

打印出来的是:

>CHB002 PatternB
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
LETTERSRANDOMSTRINGHH

这让我更接近了,因为我只从 file1.txt 打印 PatternB(我确实想将其包含在我的输出中)并且我从 file2.txt 中排除了 PatternB,这是我不想要的。但是,我还想在我想要的输出中包含 PatternA 和 PatternB。 CHB### 模式是可变的,不能依赖它。我觉得这应该是我可以在一行命令中完成而无需编写脚本的事情,但我被卡住了(也是新手)。

切勿使用范围表达式 (/start/,/end/),因为虽然它们使琐碎任务的代码稍微简洁一些,但它们需要完全重写和复制条件以应对最微小的需求变化。也永远不要使用名为 l 的变量,因为它看起来太像数字 1 了,所以会混淆你的代码。最后 - 创建单行命令永远不应该成为编写软件的目标,因为它表明你更喜欢简洁而不是好的软件中真正重要的一切,例如紧密内聚、松散耦合、效率、可移植性、清晰度、简单性和健壮性。

$ cat tst.awk
/^>/ {
    prt()
    prevBuf = currBuf
    prevKey = currKey
    currBuf = ""
    currKey = 
}
{ currBuf = currBuf [=10=] ORS }
END { prt() }

function prt() {
    if ( ( currKey == "PatternB" ) && ( prevKey == "PatternA" ) ) {
        printf "%s%s", prevBuf, currBuf
    }
}

.

$ awk -f tst.awk file1
>CHB001 PatternA
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
>CHB002 PatternB
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
LETTERSRANDOMSTRINGHH

$ awk -f tst.awk file2
$

多字符 RS

$ awk -v RS='(^|\n)>' '~/PatternA/{a=1; p=[=10=]; next} 
                       a{if(~/PatternB/) print RT p RT [=10=]; a=0}' file1

>CHB001 PatternA
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
>CHB002 PatternB
RANDOMSTRINGOFLETTERS
LETTERSRANDOMSTRINGHH
LETTERSRANDOMSTRINGHH

在顶部有一个额外的换行符,如果将 print RT p RT [=13=] 更改为 print ">" p "\n>" [=14=] 则很容易去掉。但也许并不重要。

或者,与其他 awk 一起,如果 > 没有出现在其他地方

$ awk -v RS='>' '~/PatternA/{a=1; p=[=11=]; next} 
                 a{if(~/PatternB/) print RT p RT [=11=]; a=0}' file