
次のようなファイルを解析する効率的な方法はありますか?
2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
に:
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
パターンは常に|||
; です。その後、 で始まりCSQ
、5 番目のフィールドで終わります。ただし、そのフィールドは常に であるとは限らずmissense variant
、 のように異なる場合もありますkdjdud
。
ファイルには多くの行 (60,000 行以上) があり、上記のようにこのタブデリテーブルを抽出する必要があります。そのための Python、Perl、AWK (または他の何か) ソリューションはありますか?
答え1
使用してみましょうsed
:
sed -r 's/.*\|\|\|;(CSQ[^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|.*/\1\t\2\t\3\t\4\t\5/' file.txt
python
非常に大きなファイルの操作は高速ではありませんが、これは よりもはるかに高速ですpython
。
例:
% cat file.txt
2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
% sed -r 's/.*\|\|\|;(CSQ[^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|.*/\1\t\2\t\3\t\4\t\5/' file.txt
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
答え2
Perl の使用:
perl -F'\|\|\|' -lane '$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)' file
-F'\|\|\|'
: 入力フィールドの区切り文字を|||
;に設定します。-l
: は自動的な行末処理を有効にします。これには 2 つの効果があります。まず、-n または -p と一緒に使用すると、$/ (入力レコード区切り文字) が自動的に切り詰められます。次に、$\ (出力レコード区切り文字) に octnum の値が割り当てられ、すべての print ステートメントでその区切り文字が追加されます。octnum が省略されている場合は、$\ が $/ の現在の値に設定されます。-a
: -n または -p と一緒に使用すると、自動分割モードがオンになります。@F 配列への暗黙的な分割コマンドは、-n または -p によって生成される暗黙的な while ループ内で最初に実行されます。n
: は、Perl がプログラムの周りに次のループを想定し、sed -n や awk のようにファイル名引数を反復処理するようにします。LINE: while (<>) { ... # your program goes here }
-e
: は 1 行のプログラムを入力するために使用できます。$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)
: 出力フィールド区切り文字を に設定し\t
、現在の行の 2 番目のフィールドを;
またはで分割し|
、最初の空のフィールドを削除して、残りのフィールドを出力します。
% cat file
2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
% perl -F'\|\|\|' -lane '$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)' file
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
%
答え3
これはうまくいくはずです:
cut -d"|" -f4,5,6,7,8 filename.txt | sed 's/;//g' | sed 's/|/\t/g'
例:
$ echo "2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
" | cut -d"|" -f4,5,6,7,8 | sed 's/;//g' | sed 's/|/\t/g'
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
説明
cut -d"|" -f4,5,6,7,8 filename.txt #-> split the line at | and return fields 4 to 8
| sed 's/;//g' #-> remove the ;
| sed 's/|/\t/g' #-> replace | with tab
答え4
Pythonソリューション
#!/usr/bin/env python
import re,sys
with open(sys.argv[1]) as fd:
for line in fd:
pattern=[ x for x in re.split('\|\|\||;',line)
if 'CSQ' in x]
if pattern:
print(" ".join(pattern[0].split("|")[0:5]))
テスト
OPの元のセリフを3回書き直し、少し編集してinput.txt
$ ./extract_pattern.py input.txt
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript random_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript other_variant
説明
このスクリプトは、コマンドラインで引数として指定されたファイル ( sys.argv[1]
) を開き、ファイルを 1 行ずつ読み取ります。最初に、re.split()
関数を使用して、各行を複数の区切り文字 (3 つの縦棒または ) で分割します。;
これにより、関連データを 1 つの文字列内に含めることができます。次に、 を含む 1 つの文字列を検索しますCSQ
。見つかった場合、文字列は再び文字列のリストに分割され、今度は.split()
縦棒を区切り文字として使用する関数のみが使用されます。結果のリストはスライスされ、最初の 5 つの要素 ( 部分) が取得され[0:5]
、スペースを区切り文字として使用して新しい文字列に再結合されます。