linux awk比较两个csv文件并创build一个带有标志的新文件

我有2个CSV文件,我需要比较,并获得新的格式化文件的差异。 样品在下面给出。

旧文件

DTL,11111111,1111111111111111,11111111111,Y,N,xx,xx DTL,22222222,2222222222222222,22222222222,Y,Y,cc,cc DTL,33333333,3333333333333333,33333333333,Y,Y,dd,dd DTL,44444444,4444444444444444,44444444444,Y,Y,ss,ss DTL,55555555,5555555555555555,55555555555,Y,Y,qq,qq 

新文件

 DTL,11111111,1111111111111111,11111111111,Y,Y,xx,xx DTL,22222222,2222222222222222,22222222222,Y,N,cc,cc DTL,44444444,4444444444444444,44444444444,Y,Y,ss,ss DTL,55555555,5555555555555555,55555555555,Y,Y,qq,qq DTL,77777777,7777777777777777,77777777777,N,N,ee,ee 

输出文件

我想比较旧的和新的CSV文件,并find已在新文件中产生的变化,并更新一个标志来表示这些变化

U – 如果新文件logging已更新D – 旧文件中存在的logging在新文件中删除N – 如果新文件中存在的logging在旧文件中不可用

示例输出文件是这样的。

 DTL,11111111,1111111111111111,11111111111,Y,Y,xx,xx U DTL,22222222,2222222222222222,22222222222,Y,N,cc,cc U DTL,33333333,3333333333333333,33333333333,Y,Y,dd,dd D DTL,77777777,7777777777777777,77777777777,N,N,ee,ee N 

我使用diff命令,但它也会重复UPDATEDlogging,这不是我想要的。

  DTL,11111111,1111111111111111,11111111111,Y,N,xx,xx DTL,22222222,2222222222222222,22222222222,Y,Y,cc,cc DTL,33333333,3333333333333333,33333333333,Y,Y,dd,dd --- DTL,11111111,1111111111111111,11111111111,Y,Y,xx,xx DTL,22222222,2222222222222222,22222222222,Y,N,cc,cc 5a5 DTL,77777777,7777777777777777,77777777777,N,N,ee,ee 

我使用AWK单行命令来筛选出我的logging

  awk 'NR==FNR{A[$1];next}!($1 in A)' FS=: old.csv new.csv 

这个问题是没有得到我只属于旧文件的logging。 这是

 DTL,33333333,3333333333333333,33333333333,Y,Y,dd,dd 

我也发起了一个驱动的bash脚本,以避免这个问题,但没有find很好的例子。

  myscript.awk BEGIN { FS = "," # input field seperator OFS = "," # output field seperator } NR > 1 { #flag # N - new record D- Deleted U - Updated id = $1 name = $2 flag = 'N' # This prints the columns in the new order. The commas tell Awk to use the character set in OFS print id,name,flag } >> awk -f myscript.awk old.csv new.csv > formatted.csv 

这可能适合你:

 diff -W999 --side-by-side OLD NEW | sed '/^[^\t]*\t\s*|\t\(.*\)/{s//\1 U/;b};/^\([^\t]*\)\t*\s*<$/{s//\1 D/;b};/^.*>\t\(.*\)/{s//\1 N/;b};d' DTL,11111111,1111111111111111,11111111111,Y,Y,xx,xx U DTL,22222222,2222222222222222,22222222222,Y,N,cc,cc U DTL,33333333,3333333333333333,33333333333,Y,Y,dd,dd D DTL,77777777,7777777777777777,77777777777,N,N,ee,ee N 

awk解决方案沿着同样的路线:

 diff -W999 --side-by-side OLD NEW | awk '/[|][\t]/{split($0,a,"[|][\t]");print a[2]" U"};/[\t] *<$/{split($0,a,"[\t]* *<$");print a[1]" D"};/>[\t]/{split($0,a,">[\t]");print a[2]" N"}' DTL,11111111,1111111111111111,11111111111,Y,Y,xx,xx U DTL,22222222,2222222222222222,22222222222,Y,N,cc,cc U DTL,33333333,3333333333333333,33333333333,Y,Y,dd,dd D DTL,77777777,7777777777777777,77777777777,N,N,ee,ee N 

一个好的起点可能是:

  diff -e OLD NEW 

这输出:

  5a DTL,77777777,7777777777777777,77777777777,N,N,ee,ee . 1,3c DTL,11111111,1111111111111111,11111111111,Y,Y,xx,xx DTL,22222222,2222222222222222,22222222222,Y,N,cc,cc 

这意味着它在第5行(5a)添加了一条记录,并更改了第1行和第3行(1,3c)的记录。

如果你不能使用这种格式(这将是一个好标准),那么你需要编写一个脚本,将其转换为你所描述的格式。