長いテキストファイルがあります。ファイルの内容の一部を以下に示します。
[{"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
上記のテキストファイルからIDを解析する必要があり、期待される結果は以下の通りです。
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
は各行の一致する部分のみを印刷するように-o
指示し、 はPerl 互換正規表現を有効にします。 正規表現は を探しますが、それを破棄します ( は「これまでに一致したものをすべて破棄する」という意味なので、出力には含まれません)。 次に、非( )の最長の連続を探します。grep
-P
"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
このコマンドでは、入力レコードセパレータ(RS
)がカンマに設定されています。
次に、gawk
組み込み関数は、gensub()
バック参照( ) を使用して行を目的のパターンに置き換えます\\2
。
答え4
Perl 5 ソリューション
$ perl -nle 'print join"\n",m/uniprot\":\"(.*?)\"/g' file.txt
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
$