过滤文件取决于属于另一个文件中指定的范围内的值

时间:2014-03-04 12:26:38

标签: unix awk

我想根据这两个标准过滤file1

(a)仅包含$1可以在$1中找到与file2匹配的记录(在许多情况下会有多个匹配),

(b)如果找到匹配项,则应检查$2中的file1,以确保其位于$2$3 file2指定的范围内1}}。

文件1:

seq_100|rf001 298 01 11 01 11
seq_0442|rf76 6000 01 11 10 00
seq_9999|rf54 5098 01 01 01 01

file2的:

seq_100|rf001 0 679
seq_100|rf001 700 800
seq_100|rf001 19000 22000
seq_100|rf001 23000 23500
seq_9999|rf54 800 3000
seq_9999|rf54 7000 7800
seq_9999|rf54 8000 9000

预期输出:

seq_100|rf001 298 01 11 01 11

2 个答案:

答案 0 :(得分:2)

以下是awk的另一种方式:

awk '
NR==FNR {
  line[$1,$2] = $0; 
  next
}
{
  for(key in line) {
    split(key, tmp, SUBSEP); 
    if(tmp[1] == $1 && tmp[2] > $2 && tmp[2] < $3) 
      print line[tmp[1],tmp[2]]
    }
}' file1 file2

<强>输出:

seq_100|rf001 298 01 11 01 11

<强>解释

  • 我们遍历file1并将整行存储在以column1和column2索引的二维数组中。
  • 一旦整个file1存储在内存中,我们就会遍历数组行中的每个键。
  • 我们拆分了密钥并检查第二个文件的column1是否等于密钥的第一部分,而密钥的第二部分是否在该范围内。
  • 如果一切都是黄金,我们打印线。

答案 1 :(得分:1)

你可以尝试这个awk单行,

awk 'NR==FNR{ if($1 in a) a[$1]=a[$1]","$2" "$3; else a[$1]=$2" "$3;next;} {n=split(a[$1],arr,",");for(i=1;i<n;i++){split(arr[i],b," ");if( $2 > b[1] && $2 < b[2] ){ print $0;} }}' file2 file1

awk脚本,

NR==FNR{
        if($1 in a)
                a[$1]=a[$1]","$2" "$3;
        else
                a[$1]=$2" "$3;
        next;
}
{

        n=split(a[$1],arr,",");
        for(i=1;i<=n;i++){
                split(arr[i],b," ");
                if( $2 > b[1] && $2 < b[2] ){
                        print $0;
                }
        }
}

<强>测试

sat:~# awk -f sample.awk  file2 file1 
seq_100|rf001 298 01 11 01 11