次のファイルがあります
ID A1 A2 A3
1 A G A
2 T G A
3 T A G
4 T G A
5 A A G
6 A C A
7 C T G
数千行の長さで、G、C、T、Aで構成されています。ここで、GはCを補完し、AはTを補完します。私がしたいのは、A2またはA3でA1と一致するものを検索することです。一致するものがある場合はそのままにし、そうでない場合はA2とA3を補完項目(A = T、G = Cなど)に変更し、その逆も同様です。
したがって、出力は次のようになります。
ID A1 A2 A3
1 A G A
2 T C T
3 T T C
4 T C T
5 A A G
6 A C A
7 C A C
awkを使用して、一致するIDと一致しないIDをフィルタリングできると思いました。
awk '{if($2 != $3 || $2 != $4) print $0}' mergedlist > nonmatchlist
そして
awk '{if($2 == $3 || $2 == $4) print $0}' mergedlist > matchlist
ただし、これは1つの変数(前者の場合はT、後者の場合はA)にのみ機能します。
答え1
perl -lane 'sub flip { if ($_[0] eq "T") { "A" } elsif ($_[0] eq "A") { "T" } elsif ($_[0] eq "G") { "C" } elsif ($_[0] eq "C") { "G" } else { $_[0] } } if (!($F[1] eq $F[2] or $F[1] eq $F[3])) { $F[2] = flip($F[2]); $F[3] = flip($F[3]) } print "@F"' < input
実際には素晴らしい仕事をしないので、ポートバックするのは簡単ですが、awk
見つけるのに時間がかかります。
答え2
あなたは連想配列補完的なルックアップテーブル、例:
awk '
BEGIN {
complement["A"]="T"; complement["T"]="A";
complement["C"]="G"; complement["G"]="C";
}
NR>1 && $3!=$2 && $4!=$2 {
$3 = complement[$3];
$4 = complement[$4];
}
{
print;
}
' file
答え3
@steeldriverが提案した配列に加えて、関数を定義することもできます。
awk '
BEGIN { FS == " +" }
NR == 1 {print $0 }
function CHANGE( F )
{
if ( F == "A" ) F = "T"
else if ( F == "T" ) F = "A"
else if ( F == "C" ) F = "G"
else F = "C"
return F
}
NR >= 2 {
if ( $2 == $3 || $2 == $4 ) print $0
else {
$3=CHANGE($3)
$4=CHANGE($4)
printf "%5d%3s%3s%3s\n",$1,$2,$3,$4
}
}
' file