接続: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}'

おすすめ記事