如何按名称 select 一行以及 bash 或 python 中的前一行?

How to select a row by name and also the previous row in bash or python?

假设我们有这个数据:

##sequence-region P51451 1 505
##sequence-region P22223 1 829
P22223  UniProtKB   Transmembrane   655 677 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255 
##sequence-region Q01518 1 475
##sequence-region Q96MP8 1 289
##sequence-region Q9HCJ2 1 640
Q9HCJ2  UniProtKB   Transmembrane   528 548 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255 
##sequence-region P48059 1 325
##sequence-region Q9UHB6 1 759
##sequence-region P16581 1 610
P16581  UniProtKB   Transmembrane   557 578 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255

最后的输出将是获取包含单词“transmembrane”的行及其对应的顶行:

##sequence-region P22223 1 829
P22223  UniProtKB   Transmembrane   655 677 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255 
##sequence-region Q9HCJ2 1 640
Q9HCJ2  UniProtKB   Transmembrane   528 548 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255 
##sequence-region P16581 1 610
P16581  UniProtKB   Transmembrane   557 578 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255

我正在尝试使用 grep,但我有点卡住了

谢谢!

您可以按照以下方式使用 python 完成此任务,令 file.txt 内容为

##sequence-region P51451 1 505
##sequence-region P22223 1 829
P22223  UniProtKB   Transmembrane   655 677 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255 
##sequence-region Q01518 1 475
##sequence-region Q96MP8 1 289
##sequence-region Q9HCJ2 1 640
Q9HCJ2  UniProtKB   Transmembrane   528 548 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255 
##sequence-region P48059 1 325
##sequence-region Q9UHB6 1 759
##sequence-region P16581 1 610
P16581  UniProtKB   Transmembrane   557 578 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255

然后创建文件gettransmembrane.py持有

import fileinput
for line in fileinput.input():
    if "Transmembrane" in line:
        print(prevline,end="")
        print(line,end="")
    prevline = line

然后

python gettransmembrane.py file.txt

输出

##sequence-region P22223 1 829
P22223  UniProtKB   Transmembrane   655 677 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255
##sequence-region Q9HCJ2 1 640
Q9HCJ2  UniProtKB   Transmembrane   528 548 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255
##sequence-region P16581 1 610
P16581  UniProtKB   Transmembrane   557 578 .   .   .   Note=Helical;Ontology_term=ECO:0000255;evidence=ECO:0000255

说明:fileinput 是来自 python 标准库 (1) 的模块,对于我打印的每一行和前一行,如果它有 Transmembrane 子字符串,请注意 prevline = line 在 打印后 完成。我确实将空 strs 指定为 ends,因为行的末尾已经有换行符。

(1) 如果您仅限于处理一个您事先知道名称的文件,您可以选择使用 open 进行简单文件读取,使用 fileinput 允许您使用超过 1文件(类似于 cat 命令)或使用 stdin,所以如果你有以上作为另一个命令的输出,你不必制作临时文件,但可以将所述命令的输出管道输出到 python gettransmembrane.py

如果您有 GNU grep(Linux 上的标准 grep)并且您的数据在文件 data.txt 中,您可以使用:

grep -w Transmembrane --before-context=1 --no-group-separator data.txt
  • -w 选项将使匹配仅应用于输入中的整个单词。因此,例如,Transmembrane123 将不会匹配。那可能不是你想要的。
  • --before-context=1 导致 grep 在输入中的每个匹配行之前打印一行。
  • --no-group-separator 导致 grep 在匹配行组和上一行之间不打印分隔符。通常它会打印包含 --.
  • 的分隔线