哪个 bash 命令适用于从文本文件中提取多个模式?

which bash command is good for extracting multiple pattern from text file?

我有一个非常大的文本文件,只需要从中提取一些特定的模式并保存在其他 .txt 文件中。

这是我的文本文件的格式:

"1","Dbxref=Entrez%7CGene:5008779;ID=GSPATG00000003001;Name=GSPATG00000003001;Ontology_term=GO:0005488"
"2","Dbxref=Entrez%7CProtein:XP_001422966,EMBL:CAK55568,Uniprot:A0BAK1_PARTE,Entrez%7CProtein:124390026;Derived_from=GSPATT00000003001;ID=GSPATP00000003001;isoelectric_point=10.31;molecular_weight=55095.3;Name=GSPATP00000003001;Ontology_term=GO:0005488"
"3","Alias=PTMB.459;Dbxref=Entrez%7CGene:5008781,Entrez%7CNucleotide:CR548612;ID=GSPATG00000005001;Name=GSPATG00000005001;Ontology_term=GO:0004185,GO:0006508"
"4","Dbxref=Entrez%7CProtein:XP_001422968,Entrez%7CProtein:124390028,EMBL:CAK55570,Uniprot:Q6BFB1_PARTE;Derived_from=GSPATT00000005001;ID=GSPATP00000005001;isoelectric_point=6.41;molecular_weight=48434.5;Name=GSPATP00000005001;Ontology_term=GO:0004185,GO:0006508"
"5","Alias=PTMB.456;Dbxref=Entrez%7CNucleotide:CR548612,Entrez%7CGene:5008770;ID=GSPATG00000009001;Name=GSPATG00000009001;Ontology_term=GO:0004672,GO:0004674,GO:0004713,GO:0005524,GO:0006468"
"6","Dbxref=Entrez%7CProtein:XP_001422972,Entrez%7CProtein:124390032,EMBL:CAK55574,Uniprot:Q6BFB4_PARTE;Derived_from=GSPATT00000009001;ID=GSPATP00000009001;isoelectric_point=9.79;molecular_weight=73346.4;Name=GSPATP00000009001;Ontology_term=GO:0004672,GO:0004674,GO:0004713,GO:0005524,GO:0006468"
"7","Dbxref=Entrez%7CGene:5008748;ID=GSPATG00000010001;Name=GSPATG00000010001;Ontology_term=GO:0005515,GO:0007154,GO:0035091"

我需要的是,我只需要提取所有单词: ID, Name and Ontology_term。 例如,第 7 行的预期输出为:

ID=GSPATG00000010001;Name=GSPATG00000010001;Ontology_term=GO:0005515,GO:0007154,GO:0035091"

如何在 Linux 终端中执行此操作?

通过sed,

$ sed 's/.*;\(ID[^;]*\).*;\(Name[^;]*\).*;\(Ontology_term[^;]*\).*/;;/' file
ID=GSPATG00000003001;Name=GSPATG00000003001;Ontology_term=GO:0005488"
ID=GSPATP00000003001;Name=GSPATP00000003001;Ontology_term=GO:0005488"
ID=GSPATG00000005001;Name=GSPATG00000005001;Ontology_term=GO:0004185,GO:0006508"
ID=GSPATP00000005001;Name=GSPATP00000005001;Ontology_term=GO:0004185,GO:0006508"
ID=GSPATG00000009001;Name=GSPATG00000009001;Ontology_term=GO:0004672,GO:0004674,GO:0004713,GO:0005524,GO:0006468"
ID=GSPATP00000009001;Name=GSPATP00000009001;Ontology_term=GO:0004672,GO:0004674,GO:0004713,GO:0005524,GO:0006468"
ID=GSPATG00000010001;Name=GSPATG00000010001;Ontology_term=GO:0005515,GO:0007154,GO:0035091"

[^;]* 匹配任何字符但不匹配分号零次或多次。在基本 sed 中,捕获组由 \(..\) 引用。

您的输入格式很讨厌,因为它在双引号逗号分隔字段中包含分号分隔字段。如果我们可以确定第一个分号之前的第一个字段总是无趣的并且最后一个字段也应该总是被丢弃,我们可以通过简单地拆分分号并提取我们想要的字段来作弊。

awk -F ';' '{ for (i=1; i<=NF; ++i) { sub(/"$/, "", $i);
  if ($i ~ /^(ID|Name|Ontology_term)=/) printf "%s", $i; printf "\n" } }' file

如果这些假设并不总是成立,也许您可​​以修改或预处理输入,使它们成立。事实上,我通过修剪任何最后的双引号来做到这一点。最终,解析输入并将其转换为定义明确的平面逗号或分号分隔格式(或 JSON,如果您有很多可选字段或嵌套结构)可能是最稳健和最有成效的解决方案。