与えられたファイルの2番目の列の値を好み、共通の最初の列に基づいて2つの2列ファイルをマージします。

与えられたファイルの2番目の列の値を好み、共通の最初の列に基づいて2つの2列ファイルをマージします。

1.txt2つのタブで区切られた列を含む2つのテキストファイルがあります2.txt。両方のファイルの最初の列はトークン化されたテキストで構成されています。どちらのファイルでも、最初の列は同じです。単語の順序が重要です。 2番目の列はラベルで構成されています。最初のファイルでは、トークン化は完全ですが不正確です。 2番目のファイルでは不完全ですが正確です。

1.txt:

I          3
was        5
there      6
yesterday  6
.          0

2.txt:

I          3
was        
there      12
yesterday  
.          0

各行にラベルがあるように(行の順序を維持しながら)2つのファイルをマージしたいので、2.txt次のように、より正確なファイル(ファイルのラベルなど)が優先されます。

I          3
was        5
there      12
yesterday  6
.          0

を試しましたが、join2つのタグのみが表示されるか、1つのファイルのタグのみが表示されます。

$ join 1.txt 2.txt 
I          3 3
was        5 
there      6 12
yesterday  6 
.          0 0
$ join -1 1 -2 1 -o 1.1,2.2 1.txt 2.txt
I          3
was        
there      12
yesterday  
.          0

この回答使用するとawk似ているようですが、期待した結果は得られません。私もcoreutilsを使用することを好みます。

答え1

使用awk:

awk 'NR==FNR{if (NF==2) a[$1]=$2; next}
     {print $1,($1 in a ? a[$1] : $2)}' 2.txt 1.txt
  • NR==FNR番号レコードがファイル番号レコードと同じ場合(最初のファイルにある場合)
  • a[$1]=$2最初のフィールドをキーとして使用し、2番目のフィールドを配列に保存します。
  • $1 in a ? a[$1] : $2$1ifはprintのキーですelse printaa[$1]$2

答え2

別のオプションは次のとおりです。

join 1.txt 2.txt | awk -e '{if($NF == "") print $1, $(NF - 1); else print $1, $NF}' | column -t

これは作る:

I          3
was        5
there      12
yesterday  6
.          0

これは| column -tオプションですが、素敵な列で書式設定するだけです。

関連情報