別の列の識別子と一致する値を持つ列を追加します

別の列の識別子と一致する値を持つ列を追加します

2 つのファイルがあります:

ファイル 1

hc          Value
cluster0    0.1  
cluster0    0.2  
cluster0    0.3  
cluster1    0.3  
cluster1    0.5  
cluster0    0.8  
cluster2    0.9  
cluster2    0.9  
cluster0    0.0  

ファイル2

hc       mean
cluster0 0.35
cluster1 0.4   
cluster2 0.9

そして、次のような新しいテーブルを作成したいと思います。

ファイル3

hc          Value  mean
cluster0    0.1   0.35 
cluster0    0.2   0.35 
cluster0    0.3   0.35 
cluster1    0.3   0.40 
cluster1    0.5   0.40
cluster0    0.8   0.35 
cluster2    0.9   0.90
cluster2    0.9   0.90
cluster0    0.0   0.35

これを bash で実行するにはどうすればよいですか? これを簡単に実行できるコマンドはありますか?

答え1

Awk では簡単に実行できます。

$ awk 'NR==FNR {a[$1] = FNR==1 ? $2 : sprintf("%.2f",$2); next} {print $0,a[$1]}' File2 File1
hc          Value mean
cluster0    0.1   0.35
cluster0    0.2   0.35
cluster0    0.3   0.35
cluster1    0.3   0.40
cluster1    0.5   0.40
cluster0    0.8   0.35
cluster2    0.9   0.90
cluster2    0.9   0.90
cluster0    0.0   0.35

手順は次のとおりです。

  • 最初の名前付きファイル ( NR==FNR) の行に対して、最初の列の値でインデックス付けされ、2 番目の列 (平均) の値を含む連想配列 (またはハッシュ) を作成します。平均値を浮動小数点形式で表示する必要がない場合は、この手順を、NR==FNR {a[$1] = $2}すべての値 (ヘッダーを含む) を文字列として扱う に簡略化できます。

  • それ以外の場合は、最初の列に一致するインデックスを持つ配列の値が続く行を出力します。

答え2

以下のスクリプトを試してみましたが、これも問題なく動作しました

指示

for i in `cat file2| awk '{print $1}'`; do p=`grep "$i" file2| awk '{print $2}'`; awk -v i="$i" -v p="$p" '$1 == i {$3=p;print $0}' file1; done|sed '1i hc      Value  mean'

出力

hc          Value  mean
cluster0    0.1   0.35 
cluster0    0.2   0.35 
cluster0    0.3   0.35 
cluster1    0.3   0.40 
cluster1    0.5   0.40
cluster0    0.8   0.35 
cluster2    0.9   0.90
cluster2    0.9   0.90
cluster0    0.0   0.35

関連情報