我有两个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文件,找到在新文件中发生的变化,并更新一个标志来表示这些变化
U-如果新文件记录已更新D-如果旧文件中存在的记录在新文件中被删除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命令,但它也会重复UPDATED记录,这不是我想要的。
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单行命令过滤掉我的记录以及
awk 'NR==FNR{A[$1];next}!($1 in A)' FS=: old.csv new.csv
这个问题是不能给我只属于旧文件的记录。哪个是
DTL,33333333,3333333333333333,33333333333,Y,Y,dd,dd
我也启动了一个驱动的bash脚本来解决这个问题,但没有找到一个好的例子。
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]*ts*|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)的记录。
如果你不能按原样使用这种格式(使用标准会很好),那么你需要编写一个脚本,将其转换为你描述的格式。