結合: 2 つのファイル - ただし最後の 2 つの列のみ追加します

結合: 2 つのファイル - ただし最後の 2 つの列のみ追加します

以下のファイルが与えられます:

1.txt

1, abc, 123, 456, 789
2, lmn, 123, 456, 789
3, pqr, 123, 456, 789

2.txt

1, abc, 123, 000, 000
3, lmn, 123, 000, 000
9, opq, 123, 000, 000  

出力.txt

ID, NAME, X,    1A,    1B,  2A,   2B   
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000 

私は使ったことがあるこれ参考のため。

以下を使ってみました:

join -t , -a1 -a2 -1 1 -2 1 -o 0 -o 1.2 -o 1.3 -o 1.4 -o 1.5 -o 2.4 -o 2.5 -e "MISSING" 1.txt 2.txt

これによって次のものが生成されます:

1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789,MISSING,MISSING
3, pqr, 123, 456, 789, 000, 000
9,MISSING,MISSING,MISSING,MISSING, 000, 000

何か助けて?

答え1

一人では無理だと思いますjoin。次のことができます:

join -t, -a1 -a2 -o0,1.2,1.3,1.4,1.5,2.2,2.3,2.4,2.5 -e MISSING 1.txt 2.txt |
  perl -F, -lape '@F[1..2]=@F[5..6] if $F[1] eq "MISSING";
                  $_=join",",@F[0..4],@F[7..8]'
  • -p: sed/awkのように行ごとに読み取りループを使用する
  • -a, -F,: awk と同様に、行をフィールド (配列@F) に分割します。
  • -l: 行の内容に作用します(awk入力がRS( $/) で分割され(ただし)RSには含まれず$0)、印刷前にORS( $\) が追加される場合と同様に作用します)。
  • -e ...: 各行を評価する perl [e]xpression。
  • これはほとんど英語のように読めます。フィールド 1 (インデックスが 0 から始まる 2 番目のフィールド) が「MISSING」の場合、フィールド 1 から 2 はフィールド 5 から 6 に設定されます。次に、現在のレコードの内容 ($_ は awk の $0 に相当) をフィールド 0 から 4 および 7 から 8 に設定します。

実際、同じことを次のように書くことはawkそれほど複雑ではありません。

awk -F, -vOFS=, '$2 == "MISSING"{$2=$6;$3=$7}
                 {print $1,$2,$3,$4,$5,$8,$9}'

答え2

awk だけを使用する:

awk -F, -v OFS=, '
    BEGIN {m = " MISSING"}

    # process file1
    NR == FNR {lines[$1] = $0; next} 

    # process file2
    {
        added[$1] = $4 OFS $5
        if (!($1 in lines)) {
            $4 = m
            $5 = m
            lines[$1] = $0
        }
    } 

    # print the combined output
    END {
        for (id in lines) {
            if (!(id in added)) 
                added[id] = m OFS m
            print lines[id], added[id]
        }
    }
' 1.txt 2.txt | sort -n
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000  

答え3

最初の 3 つのフィールドを結合したいようです。join新しい最初のフィールドの最初の 2 つの区切り文字を変更し、区切り文字を復元する必要があります。

join -t, -j1 -a1 -a2 -o 0 1.2 1.3 2.2 2.3 -e " MISSING" \
<(sed 's/, /\x02/;s/, /\x02/' 1.txt) <(sed 's/, /\x02/;s/, /\x02/' 2.txt) \
| sed 's/\x02/, /g'

戻り値

1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000

関連情報