ファイルから情報を抽出する

ファイルから情報を抽出する

次のようなファイルを解析する効率的な方法はありますか?

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]、スペースを区切り文字として使用して新しい文字列に再結合されます。

関連情報