使用AWK中的另一个文件查询文件的内容

问题描述 投票:1回答:2

我试图根据第二个文件中的值有条件地过滤文件。 File1包含数字,File2包含两列数字。问题是过滤掉file1中的那些行,这些行落在file2的每一行中表示的范围内。

我有一系列循环,但运行时间大于12小时,具体取决于两个文件的长度。此代码如下所示。或者,我试图使用awk,并查看松弛溢出上发布的其他问题,但我无法弄清楚如何适当地更改代码。

循环方法:

while IFS= read READ
            do  
                position=$(echo $READ | awk '{print $4}')
                    while IFS= read BED
                        do
                            St=$(echo $BED | awk '{print $2}')
                            En=$(echo $BED | awk '{print $3}')
                        if (($position < "$St"))
                            then
                                break 
                        else 
                            if (($position >= "$St" && $position <= "$En"));
                                then 
                                    echo "$READ" | awk '{print $0"\t EXON"}' >> outputfile
                            fi  
                        fi
                        done < file2
            done < file1

有类似问题的博客:

awk: filter a file with another file

awk 'NR==FNR{a[$1];next} !($2 in a)' d3_tmp FS="[ \t=]" m2p_tmp

Find content of one file from another file in UNIX

awk -v FS="[ =]" 'NR==FNR{rows[$1]++;next}(substr($NF,1,length($NF)-1) in rows)' File1 File2

file1 :(制表符分隔)

AAA BBB 1500
CCC DDD 2500
EEE FFF 2000

file2 :(制表符分隔)

GGG 1250 1750
HHH 1950 2300
III 2600 2700

预期输出将保留file1中的行1和3(在新文件file3中),因为这些记录属于第1行第2列和第3行以及第2行第2列和第3列第3行的范围。在实际文件中,它们不受行限制,即我不想查看file1的row1并与file2的row1进行比较,而是将row1与file2中的所有行进行比较以获得命中。

file3(输出)

AAA BBB 1500
EEE FFF 2000
awk logic conditional
2个回答
1
投票

单程:

awk 'NR==FNR{a[i]=$2;b[i++]=$3;next}{for(j=0;j<i;j++){if ($3>=a[j] && $3<=b[j]){print;}}}' i=0 file2 file1
AAA BBB 1500
EEE FFF 2000

阅读file2内容并将其存储在数组ab中。当读取file1时,检查整个ab阵列之间的数字并打印。

还有一个选择:

$ awk 'NR==FNR{for(i=$2;i<=$3;i++)a[i];next}($3 in a)'  file2 file1
AAA BBB 1500
EEE FFF 2000

读取File2并将整个数字范围分解并存储到关联数组a中。当我们读取file1时,我们只需要查找数组a


0
投票

另一个awk。根据文件大小,它可能有意义也可能没有意义:

$ awk '
NR==FNR {
    a[$3]=$2                    # hash file2 records, $3 is key, $2 value
    next
}
{
    for(i in a)                 # for each record in file1 go thru ever element in a
        if($3<=i && $3>=a[i]) { # if it falls between
            print               # output
            break               # exit loop once match found
        }
}' file2 file1

输出:

AAA BBB 1500
EEE FFF 2000
© www.soinside.com 2019 - 2024. All rights reserved.