各行のパターンに基づいて、2つのファイル間の1つの列から別の列に値を印刷します。

各行のパターンに基づいて、2つのファイル間の1つの列から別の列に値を印刷します。

ファイル1には2つの列が含まれています。列1には代謝経路の名前が含まれ、列2には経路に存在する遺伝子の数が含まれています。

pathway1 3   
pathway2 4  
pathway3 5  
pathway4 6  
pathway5 9

ファイル2には3つの列があります。列1にはグループ番号が含まれ、列2には特定のグループに属する代謝経路の名前が含まれ、列3には各経路に存在する遺伝子の数が含まれます。

group1  pathway1  2   
group1  pathway4  5  
group1  pathway2  3  

group2  pathway2 1  
group2  pathway3 2 

ファイル1とファイル2はcsv形式です。

目的の出力:
次のように、パス名に基づいてFile2の列3の横にあるFile1の列2の遺伝子数をどのように印刷できますか?

group1  pathway1 2 3   
group1  pathway4 5 6  
group1  pathway2 3 4  

group2  pathway2 1 4  
group2  pathway3 2 5 

答え1

joinこれがすることです:

$ join -o 1.1,1.2,1.3,2.2 -12 -21 <(sort -k2 file2) <(sort file1) 
group1 pathway1 2 3
group2 pathway2 1 4
group1 pathway2 3 4
group2 pathway3 2 5
group1 pathway4 5 6

または、入力ファイルが実際に提案されているようにコンマで区切られているが質問に表示されない場合:

$ join -t, -o 1.1,1.2,1.3,2.2 -12 -21 <(sort -t, -k2 file2) <(sort file1) 
group1,pathway1,2,3
group2,pathway2,1,4
group1,pathway2,3,4
group2,pathway3,2,5
group1,pathway4,5,6

join両方のファイルの行は共通フィールドにリンクされます。-o出力形式を設定します。ここでは、最初のファイル(1.1,1.2,1.3)のフィールド1、2、3を印刷してから、2番目のファイル()の2番目のフィールドを印刷するように指示します2.2。そして、各ファイルに接続フィールドを設定します-1-2つまり、-12 -21「file1の2番目のフィールドとfile2の最初のフィールドを結合する」という意味です。最後に、join入力をソートする必要があるため、両方のファイルをjoin

答え2

awkではこれで十分です:

awk 'NR==FNR{a[$1]=$2;next}{print $0,a[$2]}' file1 file2

サンプルファイルはスペースで区切られた形式であり、上記のコードはスペースで区切られたファイルで機能します。

file1 file2 がコンマで区切られている場合は、次のことができます。

awk 'BEGIN{FS=OFS=","}NR==FNR{a[$1]=$2;next}{print $0,a[$2]}' file1 file2

PS:awkでは、FSは入力フィールド区切りに対応し、OFSは出力フィールド区切りに対応します。デフォルトのFSとOFSは「空白」であり、あなたの場合は空白の場合は省略できます(つまり、最初のコードでは省略)。

さまざまな入力フィールド区切り記号とさまざまな出力フィールド区切り文字を組み合わせるには、次のようにします。

awk 'BEGIN{FS=" ";OFS=","}NR==FNR{a[$1]=$2;next};$1=$1{print $0,a[$2]}' file1 file2 
#The $1=$1 part is required to redisign the record according to the different Output Field Separator OFS

質問に示すように、スペースで区切られた入力ファイルとカンマで区切られた出力を持つ最後のコードは次のとおりです。

group1,pathway1,2,3                                                                                                                                                             
group1,pathway4,5,6                                                                                                                                                             
group1,pathway2,3,4                                                                                                                                                             
group2,pathway2,1,4                                                                                                                                                             
group2,pathway3,2,5

ここでオンラインでテストしてみてください。

OFS="\t"PS:スペースで区切られたファイルの場合は、より美しい出力のために(タブ)を指定できます。

答え3

perl -lane '
 if ( @ARGV == 1 ) {
  $h{ $F[0] } = $F[1];
 } else {
  print "$_ $h{ $F[1] }";
 }
' file1 file2

関連情報