同じ行にある名前を別々のペアに分割したいと思います。
TMPRSS2|pp9284 AADAT Sample1
ERG TMPRSS2|pp9284 Sample2
TMPRSS2|pp9284 ETV1 Sample3
PDE4A MIA|MIA-RAB4B|RAB4B|RAB4B-EGLN2|EGLN2 Sample4
これはおそらく
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
両方の列に複数の名前があるため、別々のペアが必要です。別のペアがある後に他のテーブルと比較したいので、このためにmysqlを使ってみました。 Rのstrsplitは、複数の名前の数が固定されている場合にのみ機能します。しかし、行ごとに異なります。 sed、awkを使用してこれを実行できますか?
値が同じままである特定の列もあり、デフォルトでは同じ行内の値は同じままです。この列をどのように印刷する必要がありますか? 3番目の列を追加しましたが、その値が新しい行にコピーされました。これを行うには、forループでprint $ 3を使用して印刷しましたが、うまくいきません。
答え1
$ awk '{split($1,a,"|"); split($2,b,"|"); for (i in a) {for (j in b) print a[i],b[j];}}' file
TMPRSS2 AADAT
pp9284 AADAT
ERG TMPRSS2
ERG pp9284
TMPRSS2 ETV1
pp9284 ETV1
PDE4A RAB4B-EGLN2
PDE4A EGLN2
PDE4A MIA
PDE4A MIA-RAB4B
PDE4A RAB4B
3番目の(SampleN
)フィールドを同時に印刷するには、$3
ループ内に印刷ステートメントを追加するだけです。
$ awk '{split($1,a,"|"); split($2,b,"|"); for (i in a) {for (j in b) print a[i],b[j],$3;}}' file
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
答え2
バッシュ使用:
# important to use parentheses, not braces, to localize changes to IFS
# the variable is purposefully unquoted
split_pipe() ( IFS='|'; echo $1 )
while read -r first second third; do
for word1 in $(split_pipe "$first"); do
for word2 in $(split_pipe "$second"); do
echo $word1 $word2 $third
done
done
done < file
答え3
GNUを使用すると、sed
次のことができます。
sed -E 's/(\|[^ |]+) /\1| /
s/(([^|]* )?([^|]*))\|(([^ ]*)(.*))/\1\6\n\2\4/
/\n/P;D' <infile
...印刷...
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
\n
1行の内容を分割して印刷し、追加の行文字を1つずつ削除するように機能します。このP
コマンドはパターンスペースに最初に表示されるewlineP
のみを印刷するため、\n
必要に応じて編集バッファの一部のみを簡単に印刷できます。
この場合、sed
すべてのビットは、空白を含まないパイプの分割された各部分に対して、編集バッファの両端に2回配置されます。sed
一番左のパイプ分割の左右に一番左と右端を挿入し、順にewlineを使用してから、右に残っている\n
すべてのパイプ分割の両端に同じ選択を挿入します。ラインの手側を挿入します\n
。したがって、パターンスペースにewlineが存在する場合は、左側のビットのみを印刷してから、パターンスペースに最初に表示されるewlineのみを削除してやり直してくださいsed
。P
\n
D
\n
最初の交換は一度だけ発生します。パイプで区切られたセクションの末尾にパイプを追加するため、最後の発生の場合でも常に区別するパイプがあります。残りの時間にはsed
置き換えが行われ、s///
パターンP
空間の最初の行が印刷され、D
同じ削除が続きます。これ以上できない場合はD
削除されます。みんなパターンスペースを解放し、自動的に次の入力ラインを取得します。
同じ操作を実行するようにPOSIX BREを作成できます。
sed ' s/\(|[^ |]\{1,\}\) /\1| /
s/^\(\( *[^ |]* *\)*\([^ |]*\)\)|\(\([^ ]*\)\(.*\)\)/\1\6\
\2\4/; /\n/P;D' <infile