如何從文字檔解析特定的 id?

如何從文字檔解析特定的 id?

我有一個很長的文字文件,部分文件內容如下所示,

[{"site":"1a2v_1","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_2","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_3","pfam":"Cu_amine_oxid","uniprot":"T12807"},{"site":"1a2v_4","pfam":"Cu_amine_oxid","uniprot":"P12808"},{"site":"1a2v_5","pfam":"Cu_amine_oxid","uniprot":"Z12809"},{"site":"1a2v_6","pfam":"Cu_amine_oxid","uniprot":"P12821"},{"site":"1a3z_1","pfam":"Copper-bind,SoxE","uniprot":"P0C918"},

我需要uniprot從上面的文本文件中解析 ids,預期結果如下所示,

P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

為了做同樣的事情,我嘗試了以下命令,但對我來說沒有任何作用,

sed -e 's/"uniprot":"\(.*\)"},{"site":"/\1/' file.txt
cat file.txt | sed 's/.*"uniprot":" //' | sed 's/"site":".*$//'

請幫我解析上面提到的 id。

提前致謝。

答案1

如果您使用的是 Linux 系統,您可以非常輕鬆地執行以下操作:

$ grep -oP '"uniprot":"\K[^"]+' file
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

指示僅列印每-ogrep的符合部分並-P啟用 Perl 相容正規表示式。正則表達式正在尋找"uniprot":"但隨後丟棄它(這\K意味著“丟棄到目前為止匹配的任何內容”,以便它不包含在輸出中)。然後,您只需尋找最長的非"( [^"]+) 段。


當然,這看起來像 JSON 數據,因此對於任何更複雜的情況,您應該使用適當的解析器,例如jq.如果您透過新增結束語來修復檔案]並使其如下所示:

[{"site":"1a2v_1","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_2","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_3","pfam":"Cu_amine_oxid","uniprot":"T12807"},{"site":"1a2v_4","pfam":"Cu_amine_oxid","uniprot":"P12808"},{"site":"1a2v_5","pfam":"Cu_amine_oxid","uniprot":"Z12809"},{"site":"1a2v_6","pfam":"Cu_amine_oxid","uniprot":"P12821"},{"site":"1a3z_1","pfam":"Copper-bind,SoxE","uniprot":"P0C918"}]

你可以做:

$ jq -r '.[].uniprot' file
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

答案2

如果您仔細觀察,您的輸入檔是一個 Python 資料結構。特別是,它是一個字典列表。我們需要附加一個右方括號。

透過 ast 模組,我們可以序列化字串,這是一個有效的 Python 資料結構。

python3 -c 'import sys, ast
ifile,key = sys.argv[1:]
str = ""
with open(ifile) as fh:
  for l in fh: str += l.rstrip()
  lod = ast.literal_eval(str)
  for d in lod: print(d[key])
' file uniprot

P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

答案3

使用gawk

awk 'BEGIN{RS=","}
/uniprot/{print gensub(/.*("uniprot":")(.*)".*/, "\\2", "g") }' input

在此指令中,輸入 Record Separator( RS) 設定為逗號。

然後gawk內建函數gensub()使用反向引用()將行替換為所需的模式\\2

答案4

Perl 5解決方案

$ perl -nle 'print join"\n",m/uniprot\":\"(.*?)\"/g' file.txt
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
$

相關內容