假设我有setA.txt
:
a|b|0.1
c|d|0.2
b|a|0.3
我也有setB.txt
:
c|d|200
a|b|100
现在我要从setA.txt
行中删除与setB.txt
具有相同前两个字段的行,因此输出应为:
b|a|0.3
我试过了:
comm -23 <(sort setA.txt) <(sort setB.txt)
但是相等是为整行定义的,所以它不起作用。我怎么能这样做?
答案 0 :(得分:3)
$ awk -F\| 'FNR==NR{seen[$1,$2]=1;next;} !seen[$1,$2]' setB.txt setA.txt
b|a|0.3
这只读取setB.txt
一次,从中提取所需信息,然后在决定要打印的行时读取setA.txt
。
-F\|
这会将字段分隔符设置为垂直条|
。
FNR==NR{seen[$1,$2]=1;next;}
FNR是到目前为止从当前文件读取的行数,NR是读取的总行数。因此,当FNR==NR
时,我们正在阅读第一个文件setB.txt
。如果是这样,请将关联数组seen
的值设置为true,1
,用于由字段1和字段2组成的键。最后,跳过其余命令并从next
行重新开始。
!seen[$1,$2]
如果我们接到这个命令,我们正在处理第二个文件setA.txt
。由于!
表示否定,如果seen[$1,$2]
为假,则条件为真,这意味着字段1和2的这种组合不在setB.txt
中。如果是,则执行默认操作,即打印该行。
答案 1 :(得分:2)
这应该有效:
If objRange.Cells(intRow, 1) = Nothing Then
End If
这是如何运作的:
sed -n 's#\(^[^|]*|[^|]*\)|.*#/^\1/d#p' setB.txt |sed -f- setA.txt
生成输出:
sed -n 's#\(^[^|]*|[^|]*\)|.*#/^\1/d#p'
然后用作管道和输出后的下一个/^c|d/d
/^a|b/d
的{{1}}脚本:
sed
答案 2 :(得分:0)
(IFS=$'|'; cat setA.txt | while read x y z; do grep -q -P "\Q$x|$y|\E" setB.txt || echo "$x|$y|$z"; done; )
解释:grep -q表示只测试grep是否可以找到正则表达式,但不输出,-P表示使用Perl语法,以便|
匹配原样,因为\Q..\E
结构
IFS=$'|'
会使bash使用|
而不是空格(SPC,TAB等)作为标记分隔符。