列と行数の異なる2つのファイルをリンクします。

列と行数の異なる2つのファイルをリンクします。

2つのファイルがあります。 file_1.txtは次のとおりです。

R1     C1     C2     C3     C4     C5
R2     C1     C2     C3     C4     C5
R3     C1     C2     C3     C4     C5
R4     C1     C2     C3     C4     C5
R5     C1     C2     C3     C4     C5
R6     C1     C2     C3     C4     C5
R7     C1     C2     C3     C4     C5
R8     C1     C2     C3     C4     C5
R9     C1     C2     C3     C4     C5
R10    C1     C2     C3     C4     C5

file_2.txtは次のとおりです。

R4 C4 C5
R6 C4 C5
R7 C4 C5
R9 C4 C5

file_1.txtのC4、C5の値をfile_2.txtの対応する値に置き換え、file_1.txtのC1、C2、C3の値はそのままにしたいと思います。

したがって、生成されたfile_3.txtは次のようになります。

R1     C1     C2     C3     C4     C5
R2     C1     C2     C3     C4     C5
R3     C1     C2     C3     C4     C5
R4     C1     C2     C3     C4_new C5_new
R5     C1     C2     C3     C4     C5
R6     C1     C2     C3     C4_new C5_new
R7     C1     C2     C3     C4_new C5_new
R8     C1     C2     C3     C4     C5
R9     C1     C2     C3     C4_new C5_new
R10    C1     C2     C3     C4     C5

すべての値は数値です。 file_1.txtとfile_2.txtの最初の列は、数値が昇順にソートされたキーフィールドです。

これは一人だけ参加すればできることですか?

答え1

この問題の一般的なアプリケーションは次のとおりです。

awk 'NR == FNR{a1[$1]=$2; a2[$1]=$3; next};
    $1 in a1{$5=a1[$1]; $6=a2[$1]};{print}' file_2.txt file_1.txt     

出力フィールド区切り文字をタブで明示的に設定する必要があるかもしれません。この場合

awk -v OFS='\t' 'NR == FNR{a1[$1]=$2; a2[$1]=$3; next};
    $1 in a1{$5=a1[$1]; $6=a2[$1]};{print}' file_2.txt file_1.txt 

答え2

これは問題を解決しませんが、join名目上、この特別な場合に機能する必要があるように聞こえますが、機能しない理由を示しています。私はjoinこのサイトであなたと同様の問題を解決するのにかなりの時間を費やしました。一意の識別子を使用した2つのファイルの関連付け

最初の方法

あなたの問題に対する解決策joinは次のとおりです。

$ join -a1 -1 1 -2 1 -o 1.1 1.2 1.3 1.4 2.2 2.3 <(sort file_1.txt) <(sort file_2.txt)
R10 C1 C2 C3  
R1 C1 C2 C3  
R2 C1 C2 C3  
R3 C1 C2 C3  
R4 C1 C2 C3 C4_new C5_new
R5 C1 C2 C3  
R6 C1 C2 C3 C4_new C5_new
R7 C1 C2 C3 C4_new C5_new
R8 C1 C2 C3  
R9 C1 C2 C3 C4_new C5_new

ご覧のとおり、ファイルjoinを整列形式で配置する必要があるため、最初にファイルの元の順序が重要な場合は、このオプションを使用すると問題が発生する可能性があります。

joinまた、値、値の有無に応じて、あるファイルまたは別のファイルから列値を条件付きで印刷する方法はありません。

2番目の方法

別のアプローチjoinは次のとおりです。

$ join -a1 -1 1 -2 1  <(sort file_1.txt) <(sort file_2.txt)
R10 C1 C2 C3 C4 C5
R1 C1 C2 C3 C4 C5
R2 C1 C2 C3 C4 C5
R3 C1 C2 C3 C4 C5
R4 C1 C2 C3 C4 C5 C4_new C5_new
R5 C1 C2 C3 C4 C5
R6 C1 C2 C3 C4 C5 C4_new C5_new
R7 C1 C2 C3 C4 C5 C4_new C5_new
R8 C1 C2 C3 C4 C5
R9 C1 C2 C3 C4 C5 C4_new C5_new

繰り返しますが、これは必要なものと似ていますが、条件付きロジックを使用してあるファイルまたは別のファイルの列を印刷することはできません。

3番目の方法

これは動作しますがawkfile_2.txt

$ join -a1 -1 1 -2 1 -o 1.1 1.2 1.3 1.4 2.2 2.3 1.5 1.6 1.7 <(sort file_1.txt) <(sort file_2.txt) | awk '{$7=$8=""}1'
R10 C1 C2 C3 C4 C5  
R1 C1 C2 C3 C4 C5  
R2 C1 C2 C3 C4 C5  
R3 C1 C2 C3 C4 C5  
R4 C1 C2 C3 C4_new C5_new  
R5 C1 C2 C3 C4 C5  
R6 C1 C2 C3 C4_new C5_new  
R7 C1 C2 C3 C4_new C5_new  
R8 C1 C2 C3 C4 C5  
R9 C1 C2 C3 C4_new C5_new  

今参加しましたか?

ジョイン市場は非常に狭く、便利なツールになることができます。代替タイプの質問(あなたの質問がより適切な場合)の場合awkperlまたは同じツールがsedより適切です。

関連情報