【问题】写脚本实现,可以用shell、perl等。把文件b中有的,但是文件a中没有的所有行,保存为文件c,并统计c的行数。
翻译成人话就是,假设有一个文件a是:
a
b
c
d
文件b是:
1
2
3
4
a
b
现在要求输出“b有a没有”的行,即1 2 3 4,然后wc -l
一下。
【思路】两个文件比较,第一想法就是diff
,但是diff
无论是-c
还是-y
会牵扯进大量的> < + -
不说,而且diff命令是直白对比,即使字母相同但所在行不同,也会被diff
记录。如果再用for in
语句然后一项一项对比也不会很清晰的解决这个问题,所以要换个方法。
第二个方法就是comm
命令,但是这个命令有一个前提,就是要sort
排序,comm
比diff
高明之处在于它只比较内容而不在意是否同一行,但是要注意对比文件的先后。comm -12 a b
是找”a和b都有”的项,comm -23 a b
就是找”a有而b没有”。
【解答】perl我不会,我就用shell写:
1
2
3
4
5
6
#written by ChrisChan @ 2016-4-21
sort a.txt>a1.txt #排序,不然会有提示
sort b.txt>b1.txt
comm -23 b1.txt a1.txt >c.txt #由于是要找b有a没有的,就要b写在前,a写在后
echo $(cat c.txt|wc -l)
其实还有一个更简单的,只用一句话:
1
grep -v -x b.txt -f a.txt|wc -l
很多书上不写grep -x -f
的意思,这里补一下:-f
:指定范本文件,其内容含有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每列一个范本样式。-x
:只显示全列符合的列。
从一个题就能轻松看出shell的能力级别,用diff死纠缠就是初级,用comm就是中级,而grep就是高级。的确是一个好题。
【补充】如果考python,求这种类似“你有我没有”的东西,用set里面的差集算法。
1
2
3
4
5
6
7
8
9
10>>>A={1,2,3,4}
>>>B={3,4,5,6}
>>>print(A-B)
set([1,2]) #A有B没有
>>>print(A ^ B)
set([1,2,5,6]) #差集的补集
>>> A&B
{3, 4} #交集
>>> A|B
{1, 2, 3, 4, 5, 6} #全集