awk または sed を使用して csv diff をより読みやすい形式に変換する方法

awk または sed を使用して csv diff をより読みやすい形式に変換する方法

awk または sed (どちらもあまり使用したことがなく、csv データの処理には主に grep と cut を使用していたため、どちらかはわかりません) を使用して、2 つの .csv ファイル間の違いをより読みやすい形式に変換する方法の例を教えていただけますか。

たとえば、古い .csv ファイルと新しい .csv ファイルから diff を生成した場合、実際には列の数が多いため、はるかに複雑になる可能性があります。

2,3c2,3
< Barbara,1093,19
< Magdaline,2093,20
\ No newline at end of file
---
> Barbara,1011,19
> Magdaline,12093,20
\ No newline at end of file

どうすればこの形式に変換できますか:

Barbara  1093 1011 
Magdaline 2093 12093

新しい形式では、データの最初の列は、行を識別するための diff の両方の部分の最初の列の値です。2 番目の列には最初の csv ファイルのデータ (古い値) が含まれ、3 番目の列には 2 番目の csv ファイルの値 (新しい値) が含まれます。

awk または sed を使用してこのようなテキスト変換を実行するにはどうすればよいでしょうか?

ありがとう。

答え1

2 つの連想配列で awk を使用します。次のようになります。

awk -F, '
  /^</{sub("< *","",$1);old[$1]=$2}
  /^>/{sub("> *","",$1);new[$1]=$2}
  END{ for(k in old) print k,old[k],new[k] }
'

必要に応じて、すべてをスペースで区切られた 1 行に連結することもできますが、私は複数行の方が好きです。 ;) 以下にサンプルを示します。

sauer@humpy:~$ cat file
< a,b,c
> a,d,e
gibberish
< 1,2,3
> 1,4,5
sauer@humpy:~$ awk -F, '
  /^</{sub("< *","",$1);old[$1]=$2}
  /^>/{sub("> *","",$1);new[$1]=$2}
  END{ for(k in old) print k,old[k],new[k] }
' < file
a b d
1 2 4

ああ、古い awk を使用している場合は、 を"< *"正規表現ではなく固定パターンにする必要があるかもしれません。そのため、 を削除し*、方向指示子の後にリテラルの量のスペースを入れます。

関連情報