次のように、20,000行を超えるテキストファイルがあります。
7 128550681 128550681 Intron:1:36:RETAINED-RETAINED;Transcript:NM_001135914.1;Gene:KCP:protein_coding 1 1 0 0
1 17718672 17718672 Intron:9:16:RETAINED-RETAINED;Transcript:NM_207421.4;Gene:PADI6:protein_coding 1 1 0 0
1 17718672 17718672 Intron:9:16:RETAINED-RETAINED;Transcript:NM_207421.4;Gene:PADI6:protein_coding 1 1 0 0
4 86035 86035 Exon:4:5:RETAINED;Transcript:NM_001286052.1;Gene:ZNF595:protein_coding 1 1 0 0
3 12942851 12942851 Intron:14:14:SKIPPED-ALTTENATIVE_3SS;Transcript:NM_001134382.2;Gene:IQSEC1:protein_coding 1 1 0 0
必要なのは、4番目の列にGene:genenameのみが含まれているため、出力は次のようになります。
7 128550681 128550681 Gene:KCP 1 1 0 0
1 17718672 17718672 Gene:PADI6 1 1 0 0
1 17718672 17718672 Gene:PADI6 1 1 0 0
4 86035 86035 Gene:ZNF595 1 1 0 0
3 12942851 12942851 Gene:IQSEC1 1 1 0 0
Gene:genename
*:
押したり分割したりすると、問題は常に同じ場所に表示されません。;
私は特定の列を選択する方法、特定のパターンを含む行を見つける方法など、非常に基本的なawk / sedを知っています。
答え1
awk
次のコマンドを使用してこれを実行できました。
awk '{sub(/^.*;/,"",$4); print}' input
これにより、最後の項目までの列4の内容がすべて削除され、機能しなくなる可能性があり;
ます(Steeldriverの説明を参照)。この場合は、明確な説明を含む質問を更新してください。
答え2
awk
POSIX 定義構造にのみ使用されます。
awk 'match($4, /Gene:(.+)\:/){ $4=substr($4, RSTART, RLENGTH-1) }1' file
出力をより整理するには、出力をタブ区切りの| column -t
列にパイプします。場所がわからない場合は、パターンをGene:genename
変更してawk
行内の任意の場所を見つけて、4番目の列を希望の値に変更します。$4
(フルライン)に変更すると$0
正常に動作します。
awk 'match($0, /Gene:(.+)\:/){ $4=substr($0, RSTART, RLENGTH-1) }1' file
答え3
perl -pale 's#(?:\H+\h+){3}\K\H+#($F[3] =~ /(?:^|;)(Gene:[^:]+)/)[0]#e' input-file.txt
°4番目のフィールドの遺伝子位置が固定されていない場合は、上記のように動作できます。
°正規表現で4番目のフィールドをゼロにし、コマンド(?:\H+\h+){3}\K\H+
置換セクションで使用されている他の正規表現にすぐに置き換えますs///e
。
答え4
真珠:
perl -F'\h+' -lane '
for ( $F[3] ) {
my $a = index(";$_", ";Gene:" );
my $b = index(";$_", ":", $a+6 );
$_ = substr(";$_", $a+1, $b-$a-1);
}
print join "\t", @F;
' input-file.txt
出力:
7 128550681 128550681 Gene:KCP 1 1 0 0
1 17718672 17718672 Gene:PADI6 1 1 0 0
1 17718672 17718672 Gene:PADI6 1 1 0 0
4 86035 86035 Gene:ZNF595 1 1 0 0
3 12942851 12942851 Gene:IQSEC1 1 1 0 0
$ 128550681 128550681 Gene:$$$ 1 1 0 0
説明する:
perl
オプション:-n
=>入力内容を1行ずつ読み込むように呼び出します。-F
=>作成しますFS = horizontal whitespace
。-a
=>各行をフィールド(-F
オプション設定に応じてFSまたはデフォルトで単一のスペース)に分割し、配列に保存します@F
。-l
=>作成しますRS = ORS = "\n"
。-e
=>次の内容はPerl
コードとして扱われ、すべての行、つまりレコードに適用されます。
data structures
関連:@F
=> レコードを分割して得られたフィールドで埋められた配列。インデックスは0から始まります。$F[3]
レコードの4番目のフィールドにも同様です。$a
;Gene:
=> 4番目のフィールドに部分文字列の位置を保存します。$b
=>部分文字列の位置を4番目のフィールドに保存すると、その:
位置の後に6桁を見つけることができます;Gene:
。 IOW、:
次に2番目を見つけました;Gene
。注:検索文字列にセミコロンを入力します。つまり、$F[3]
場所はGene:
どこにでもある可能性があるため、4番目のフィールドの先頭にもあります。これはこの可能性に対処するためのものです。$_
$F[3]
=>ループ内にローカライズされたバージョンを保存しますfor
。内蔵機能は情報をsubstr
抽出して再保存します。gene:...
$F[3]
- 注:
my
変数定義の前の修飾子は、$a,$b
それを範囲がループに制限される語彙変数として表示しますfor
。 - 注:現在のレコード/行はループ
$_
内で参照されません。for
ループ期間for
が$F[3]
。
GNU Sed:
sed -Ee '
s/\S+/\n&\n/4
s/\n(.*;)?(Gene:[^:]+):.*\n/\2/
' input-file.txt
説明する:
- 4番目のフィールドを改行文字で表示します。
- 現在行の領域を杭打ちした後、必要なデータ(この場合)を見つけてください
Gene:
。as many non colons we meet on the way before we hit the next colon
- この方法は、個々のフィールド間に存在する間隔を妨げません。これは重要かもしれませんし、重要ではないかもしれません。
- 注:注:4番目のフィールドに遺伝子があるとします。複数の遺伝子の場合は、エラーや警告を表示せずに、レコードの4番目のフィールドにある最後の遺伝子を自動的に選択します。