1行にgene_idと遺伝子名を含むファイルがあります。次の言葉に変えたいです。遺伝子ID後ろの言葉遺伝子またはそれ以降製品またはそれ以降スプロット(一部欠落している場合があります。)
以下は一行の例です。
chrM Gnomon CDS 8345 8513 . + 1 gene_id "cds-XP_008824843.3"; transcript_id "cds-XP_008824843.3"; Parent "rna-XM_008826621.3"; Dbxref "GeneID:103728653_Genbank:XP_008824843.3"; Name "XP_008824843.3"; end_range "8513,."; gbkey "CDS"; gene "semaphorin-3F"; partial "true"; product "semaphorin-3F"; protein_id "XP_008824843.3"; sprot "sp|Q13275|SEM3F_HUMAN";
chrM StringTie exon 2754 3700 . + . gene_id "cds-YP_007626758.1"; transcript_id "cds-YP_007626758.1"; Parent "gene-ND1"; Dbxref "Genbank:YP_007626758.1,Gene "ID:15088436"; Name "YP_007626758.1"; Note "TAAstopcodoniscompletedbytheadditionof3'AresiduestothemRNA"; gbkey "CDS"; gene "ND1"; product "NADHdehydrogenasesubunit1"; protein_id "YP_007626758.1"; transl_except "(pos:3700..3700%2Caa:TERM)"; transl_table "2";
私は以下を達成するためにsedを使用しようとしました。
sed -E 's/[^gene_id] .*?;/[^gene] .*?;|[^sprot] .*?;|[^product] .*?;/g'
しかし、結果は正しくありません。
chrM Gnomon CDS 8345 8513 . + 1 gene_id "cds-XP_008824843.3"[^gene] .*?;|[^sprot] .*?;|[^product] .*?;
chrM StringTie exon 2754 3700 . + . gene_id "cds-YP_007626758.1"[^gene] .*?;|[^sprot] .*?;|[^product] .*?;
ところで、行をすべて保存したいのですが、その後ろに単語があります。遺伝子ID、このように:
chrM Gnomon CDS 8345 8513 . + 1 gene_id "semaphorin-3F"; transcript_id "cds-XP_008824843.3"; Parent "rna-XM_008826621.3"; Dbxref "GeneID:103728653_Genbank:XP_008824843.3"; Name "XP_008824843.3"; end_range "8513,."; gbkey "CDS"; gene "semaphorin-3F"; partial "true"; product "semaphorin-3F"; protein_id "XP_008824843.3"; sprot "sp|Q13275|SEM3F_HUMAN";
chrM StringTie exon 2754 3700 . + . gene_id "ND1"; transcript_id "cds-YP_007626758.1"; Parent "gene-ND1"; Dbxref "Genbank:YP_007626758.1,Gene "ID:15088436"; Name "YP_007626758.1"; Note "TAAstopcodoniscompletedbytheadditionof3'AresiduestothemRNA"; gbkey "CDS"; gene "ND1"; product "NADHdehydrogenasesubunit1"; protein_id "YP_007626758.1"; transl_except "(pos:3700..3700%2Caa:TERM)"; transl_table "2";
または次のようになります(他のものを見逃した場合)。
chrM Gnomon CDS 8345 8513 . + 1 gene_id "sp|Q13275|SEM3F_HUMAN"; transcript_id "cds-XP_008824843.3"; Parent "rna-XM_008826621.3"; Dbxref "GeneID:103728653_Genbank:XP_008824843.3"; Name "XP_008824843.3"; end_range "8513,."; gbkey "CDS"; gene "semaphorin-3F"; partial "true"; product "semaphorin-3F"; protein_id "XP_008824843.3"; sprot "sp|Q13275|SEM3F_HUMAN";
chrM StringTie exon 2754 3700 . + . gene_id "ND1"; transcript_id "cds-YP_007626758.1"; Parent "gene-ND1"; Dbxref "Genbank:YP_007626758.1,Gene "ID:15088436"; Name "YP_007626758.1"; Note "TAAstopcodoniscompletedbytheadditionof3'AresiduestothemRNA"; gbkey "CDS"; gene "ND1"; product "NADHdehydrogenasesubunit1"; protein_id "YP_007626758.1"; transl_except "(pos:3700..3700%2Caa:TERM)"; transl_table "2";
どんな助けでも大変感謝します。
ベストアンサー1
gene
次のperlスクリプトは、各入力ラインで、およびを順番に一致させようとしますproduct
(つまり、製品より遺伝子を、sprotsよりも製品を優先します)。sprot
そのうちの1つが一致すると、一致する単語が抽出されます。単語が二重引用符で囲まれているとします。
一致するものが見つかったら、gene_id
次の単語を抽出された単語に置き換えます。
変更の有無にかかわらず、対応する行が印刷されます。
#!/usr/bin/perl
while (<>) {
my $word = '';
if (m/\b(?:gene)\s+("[^"]*")/) {
$word = $1;
} elsif (m/\b(?:product)\s+("[^"]*")/) {
$word = $1;
} elsif (m/\b(?:sprot)\s+("[^"]*")/) {
$word = $1;
};
if ($word) {
s/\bgene_id\s+(?:"[^"]*")/gene_id $word/
};
print;
}
あるいは、ループを使用して一致するキーワードを繰り返すように作成することもできます。
#!/usr/bin/perl
while (<>) {
my $word = '';
foreach my $match (qw(gene product sprot)) {
if (m/\b(?:$match)\s+("[^"]*")/) {
$word = $1;
last; # first match wins, exit this loop
}
};
if ($word) {
s/\bgene_id\s+(?:"[^"]*")/gene_id $word/
};
print;
}
IMO、このバージョンは読みやすく理解しやすいので、より良いです(特にループはforeach
単語リストを繰り返すことを強調します)。さらに、$word = $1
ステートメントを繰り返す必要はありません。ステートメントを変更したり追加のコードを追加する必要がある場合は、3回ではなく1回だけ実行すると、間違いの可能性が低くなります。 「繰り返しないでください」は、このような小規模プログラムではそれほど重要ではありませんが、大規模プログラムでは非常に重要です。それにもかかわらず、重複を避けたり最小化したりするのは良いプログラミング習慣です。
一致する順序が重要でない場合(たとえば、どの項目が検索されるかを問わない場合は、その項目のみが検索されます)、スクリプトを簡素化できます。
#!/usr/bin/perl
while (<>) {
my ($word) = m/\b(?:gene|product|sprot)\s+("[^"]*")/;
if ($word) {
s/\bgene_id\s+(?:"[^"]*")/gene_id $word/
};
print;
}
使用するスクリプトのバージョンに関係なく、次のように保存しreplace.pl
て実行可能にしますchmod +x replace.pl
。またはすべて、、、replace1.pl
でreplace2.pl
試してみてくださいreplace3.pl
。次に、次のように実行します。
$ ./replace.pl input.txt
chrM Gnomon CDS 8345 8513 . + 1 gene_id "semaphorin-3F"; transcript_id "cds-XP_008824843.3"; Parent "rna-XM_008826621.3"; Dbxref "GeneID:103728653_Genbank:XP_008824843.3"; Name "XP_008824843.3"; end_range "8513,."; gbkey "CDS"; gene "semaphorin-3F"; partial "true"; product "semaphorin-3F"; protein_id "XP_008824843.3"; sprot "sp|Q13275|SEM3F_HUMAN";
chrM StringTie exon 2754 3700 . + . gene_id "ND1"; transcript_id "cds-YP_007626758.1"; Parent "gene-ND1"; Dbxref "Genbank:YP_007626758.1,Gene "ID:15088436"; Name "YP_007626758.1"; Note "TAAstopcodoniscompletedbytheadditionof3'AresiduestothemRNA"; gbkey "CDS"; gene "ND1"; product "NADHdehydrogenasesubunit1"; protein_id "YP_007626758.1"; transl_except "(pos:3700..3700%2Caa:TERM)"; transl_table "2";