问题:
我有2个文件,每天会根据一些在线Feed进行更新,文件包含带输入的内容,每天会添加一些新行,有些会被删除。此外,每天文件中的行的顺序也会改变。所以我想提取今天添加的行,还想知道昨天删除了多少行?
我遵循的方法:
假设说3个文件2017-07-17.txt , 2017-07-18.txt and 2017-07-19.txt
文件的数据如下。
2017-07-17.txt
a
b
c
2017-07-18.txt
a
b
d
e
f
2017-07-19.txt
f
e
a
c
b
d
g
在前两个文件上做了差异。
3d2
< c
4a4,5
> e
> f
从输出中可以轻松提取数据并知道删除的内容和添加的内容。但我的输入范围是每天100k到200k的数据行,因此使用diff
无效。
我在这种方法中面临的问题
当有一天说2017-07-19.txt
输入改变了它的顺序时,diff
逻辑在线扫描时非常有效。
$ diff 2017-07-18.txt 2017-07-19.txt
0a1,2
> f
> e
1a4
> c
4,5c7
< e
< f
---
> g
我可以使用任何解决方案来获得这样的输出。
预期输出:
$ diff 2017-07-18.txt 2017-07-19.txt
Addeed : c
g
Deleted : None
答案 0 :(得分:2)
$ cat awk-script
NR==FNR{a[$0];next}
{
if($0 in a)
a[$0]=1
else
add=add"\t"$0"\n"
}
END {
for(i in a)
if(a[i]!=1)
del=del"\t"i"\n"
printf "Added:%s\n",(add)?add:"None\n"
printf "Deleted:%s",(del)?del:"None\n"
}
$ awk -f awk-script 2017-07-18.txt 2017-07-19.txt
Added: c
g
Deleted:None
答案 1 :(得分:1)
这应该这样做。但请注意,此解决方案将使您在内存中读取整个文件。
f1 = open("2017-07-18.txt")
f2 = open("2017-07-19.txt")
lines1 = set(f1.readlines())
lines2 = set(f2.readlines())
print lines2 - lines1 # added today
print lines1 - (lines2 & lines1) # deleted today
答案 2 :(得分:1)
在awk中:
$ awk '
NR==FNR{ a[$1]; next } # hash first file contents to a
{
if($1 in a) # if second file item is found in a
delete a[$1] # delete it
else b[$1] # otherwise add it to b hash
}
END { # in the end
print "Added:"
for(i in b) # added are in b
print i
print "Deleted:"
for(i in a) # deleted are in a
print i
}' 2017-07-18.txt 2017-07-19.txt # mind the order
Added:
c
g
Deleted:
答案 3 :(得分:0)
findstr /v /x /L /g:filename1 filename2 |find /c /v ""
可能产生两个文件之间的差异计数(不确定200k行是否会受到任何限制)
在filename2中找到/v
没有/x
完全匹配/L
字面/g:
此文件中的行的行。将结果输出到find
,然后/c
计算/v
不匹配""
的上一个命令中的行(即计算前一行的行数)命令)
要将其指定给变量,请使用
for /f %%a in ('findstr /v /x /L /g:filename1 filename2 ^|find /c /v "" ') do set count=%%a
(注意引号和管道前插入的插入符号)
答案 4 :(得分:0)
awk '
# add and remove depending in wich file
{ A[$1] += (FNR==NR) * 2 - 1 }
END {
# set in different category depending of count + create human list
for( a in A){ T[A[a]] = T[A[a]] "\n " a }
# display result (thanks to @CWLiu very nice code)
printf "Added: %s\n", (T[1]) ? T[1] : "None"
printf "Deleted: %s\n", (T[-1]) ? T[-1] : "None"
}
' 2017-07-19.txt 2017-07-18.txt
为了获得咬合内存消耗,我们可以删除A [x]元素,当它在第一部分达到0或至少在END部分的for循环中丢弃