我的文件 A 有两列,如下所示:
7000000185249100 162280
7000000185249048 235500
7000000185249052 755361
7000000185249068 427550
7000000185249070 269102
7000000185249081 291122
我的文件 B 包含三列,如下所示:
7000000185249100 1622651 1623044
7000000185249048 235104 235805
7000000185249146 2500324 2502635
7000000185249100 1218818 1221734
7000000185249468 88587 89699
7000000185249239 299691 300277
7000000185249315 769635 769986
7000000185249374 1548986 1549747
所以我想做的是打印文件 A 中的行,
- 如果文件 A 中第一列的数字与文件 B 中第一列的数字匹配,并且
- 文件A中第二列的数字在文件B中第二列和第三列的数字范围内。
预期输出将是:
7000000185249048 235500
我尝试使用以下代码,但失败了。
awk -F '\t' 'FNR==NR{a[$1,$2,$3]=$0;next}{if(b=a[$1, >=$2 && <= $3]){print b}}' file B file A
答案1
用于
join
查找共同点第一名字段,然后用于bash
比较值:join --nocheck-order -j 1 A B | while read a b c d ; do [[ ( b -le d && b -ge c ) || ( b -le c && b -ge d ) ]] && echo $a $b done
这OP规格说明“文件A第二列的数字在文件B第二列和第三列的数字范围内
[[
"。这个范围可能没有排序,因此和之间的逻辑]]
会以任何一种方式处理它。示例:- 如果A2=3,B2=2, 和B3=4,与 相匹配
( b -le d && b -ge c )
。 - 如果A2=3,B2=4, 和B3=2,与 相匹配
( b -le c && b -ge d )
。
- 如果A2=3,B2=2, 和B3=4,与 相匹配
不太好GNU
sed
转换文件每一行的代码乙分成两个管道numgrep
搜索文件的命令A对于范围,那么e
估价命令。由于命令的结果列表可能具有冗余输出,因此将其通过管道传输到awk
执行未排序的独特的:sed -n \ 's#\(\w*\)\W*\(\w*\)\W*\(\w*\)#numgrep /\1/ A\|numgrep /\2..\3,\3..\2/#e /./p' B | awk '!a[$0]++'
任一方法的输出:
7000000185249048 235500