只有当它们在一系列文件中一个接一个地出现时,有没有办法提取两个连续的记录?
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
我正在尝试提取两个连续的记录,但前提是这些记录一个接一个地出现。我正在处理看起来像这样的文件:
#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