シェルスクリプトを使用して、2つのファイルのデータを1つのファイルにマージする必要があります。

シェルスクリプトを使用して、2つのファイルのデータを1つのファイルにマージする必要があります。

ファイル 1 には以下が含まれます。

hour value1           
01    25               
02    24              
03    24               
04    27  
05    30

ファイル 2 には以下が含まれます。

hour   value2   
01     03   
03     05   
05     03

私は結果が次のようになりたいです。

hour value1 value2   
01     25     03  
02     24     00  
03     24     05  
04     27     00  
05     30     03 

答え1

$ join -o1.1,1.2,2.2 -a1 -e 00 file1 file2 | column -t
hour  value1  value2
01    25      03
02    24      00
03    24      05
04    27      00
05    30      03

-o1.1,1.2,2.2表示するリレーショナル結合ジョブの出力フィールドを指定します。形式はですfile_number.field_number

-a12番目のファイルのどのエントリとも一致しなくても、1番目のファイルのすべての行を取得したいと言います。

-e 00欠落している値は文字列に置き換える必要があると言います00

これは、両方のファイルが同じ方法でソートされていると仮定します。

答え2

Awkこれを行うにはスクリプトを使用できます。両方のファイルを解析し、ヘッダーをスキップし、内容のハッシュマップを作成し、file2file1のファイルがある場合は列1の値を印刷します(そうでない場合)、00指示に従ってカスタム文字列を印刷します。

#!/usr/bin/env awk

BEGIN {
    printf "hour value1 value2\n"
}

NR>1 && FNR==NR {
    hash[$1]=$2; next
}

FNR>1 {
    if ($1 in hash) {
        printf "%s\t%s\t%s\n",$1,$2,hash[$1]
    } else {
        printf "%s\t%s\t%s\n",$1,$2,"00"
    }
}

このスクリプトを次のように実行します。

awk -f script.awk file2 file1
hour value1 value2
01      25      03
02      24      00
03      24      05
04      27      00
05      30      03

これにより、目的の結果が得られます。


読み取れない単一のコマンドラインバージョンは次のとおりです。

awk 'BEGIN{printf "hour value1 value2\n"} NR>1 && FNR==NR{hash[$1]=$2; next} FNR>1 { if ($1 in hash) {printf "%s\t%s\t%s\n",$1,$2,hash[$1] } else {printf "%s\t%s\t%s\n",$1,$2,"00"} }' file2 file1

答え3

入力ファイルがすでにフィールドhour値でソートされている場合は、次の方法を試してください。参加する+アッ管路:

join --header -a1 file1 file2 | awk 'NF<3{ $0=$0 OFS "00" }1' | column -t

出力:

hour  value1  value2
01    25      03
02    24      00
03    24      05
04    27      00
05    30      03

  • -a1- ファイルからペアリングできない行を印刷します。1

  • NF<3{ $0=$0 OFS "00" }- 一致しない空のフィールドを次に置き換えます。00

関連情報