可能这对于shell程序员来说是一个非常基本的问题。 但假设我有一个文本文件A和B 和B是A的子集。基本shell编程
我想创建一个包含(A-B)数据的文本文件C.
因此省略所有的通用线。
在文件中的线是数字数据:像
id , some aspect, other aspec.
感谢。
可能这对于shell程序员来说是一个非常基本的问题。 但假设我有一个文本文件A和B 和B是A的子集。基本shell编程
我想创建一个包含(A-B)数据的文本文件C.
因此省略所有的通用线。
在文件中的线是数字数据:像
id , some aspect, other aspec.
感谢。
sort a b | uniq -u
如果你想要的是A和B之间的相同的线,你可以使用uniq -d
sort a b | uniq -d
在假定的是,在A的数据和B是,正好是一样。数据集中不能有任何丢失空格或制表符。如果有,则必须首先使用sed
,tr
或awk
清理数据。
编辑
正如彼得。 O指出,如果碰巧在文件a
中出现重复,这将失败。使用awk
sort <(sort -u a) b | uniq -u
方式一:如果这是一个问题,你可以这样做修复它。重定向以保存任何文件中的内容而不是STDOUT
。
awk 'FNR == NR { data[ $0 ] = 1; next } FNR < NR { if ($0 in data) { next } print $0 }' fileB fileA
修订具有更有效的命令。由于Peter.O:
awk 'FNR==NR{data[$0]; next}; $0 in data{next}; 1' fileB fileA
只需要几点让它变得更加consise(和更快):1)你不需要为数组赋值;只是指它创建索引部分。 2)第二次FNR测试是不需要的,因为前面的'next'迎合了这一点。 3)“if”测试是多余的,因为数据中的“$ 0”本身就是一个测试。 4)任何非零值都会导致$ 0被打印,所以'print $ 0'可以是一个“布尔值”:'awk'FNR == NR {data [$ 0];下一个};数据{next} $ 0; 1'fileB fileA' – 2012-04-27 04:25:37
@ Peter.O:谢谢你的建议。我把你的命令加到答案上。 – Birei 2012-04-27 08:01:35
您也不需要那些空语句(尾随分号),而不是在数据中测试$ 0并在下一步做测试,然后再隐式打印,您可以忽略测试,并且不需要第一个下一步(除非fileB是巨大的,效率是一个问题),所以你可以把它写成'awk'FNR == NR {data [$ 0]}!($ 0 in data)'fileB fileA'。 – 2012-11-16 05:31:57
有一个名为comm
实用程序的二手只是这样的:
comm -23 A B > C
其中-2
手段“拒绝独特的文件B线”(你说有AREN 't any),-3
表示“拒绝这两个文件共有的行”。
@BartonChittenden使得一个好点:
comm -23 <(sort A) <(sort B) > C
注意这两个文件都必须是 – 2012-04-27 02:07:27
+1给我展示'comm',这是我从来没有听说过的。+10给我展示'<(command)'我从来没有听说过。 – 2012-04-27 13:18:53
这就是所谓的“过程替代”,可以让你对待输出一个命令,就好像它是一个文件一样,见手册页。 – 2012-04-27 15:35:27
awk 'FNR==NR{a[$0];next}(!($0 in a))' B A
您还没有提到,无论哪种方式,你的数据是否可以包含重复行。如果可以的话,那么请注意,当“A”中存在不匹配的重复行时,Tim Pote的'sort' +'uniq'方法**不起作用。 'awk'和'comm'方法可以在'A'中重复使用。 – 2012-04-27 05:50:56