接続: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など、1行ずつ読み取りループを使用します。
  • -a-F,:awkと同様に、行をフィールドに分割します(@F配列に入れます)。
  • -l:行の内容に応じて動作します(awk()で入力を分割するのと似ています(ただし束縛されていません)。印刷する前に()が追加されます。RS$/RS$0ORS$\
  • -e ...:perl[e] 各行を評価する式です。
  • そうすれば、ほとんど英語に似て読みます。フィールド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つの領域に参加したいようです。次に、新しい最初のフィールドの最初の2つの区切り文字を変更し、join区切り文字を復元する必要があります。

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

関連情報