Variables awk设置变量以形成范围

Variables awk设置变量以形成范围,variables,awk,Variables,Awk,我有以下两个文件: 文件1: 1 290 rs1345 2 450 rs5313 1 1120 rs4523 2 790 rs4325 文件2: 1 201 LDLR 2 714 APOA5 1 818 NOTCH5 1 514 TTN 我只想隔离文件2中第二个字段与文件1中第二个字段的距离在100个单位以内的行(如果字段1匹配): 所需输出:(注意,第三个字段来自文件1中的匹配行) 我尝试使用以下代码: for i in {1..4} #there are 4 lines in file2

我有以下两个文件:

文件1:

1 290 rs1345
2 450 rs5313
1 1120 rs4523
2 790 rs4325
文件2:

1 201 LDLR
2 714 APOA5
1 818 NOTCH5
1 514 TTN
我只想隔离文件2中第二个字段与文件1中第二个字段的距离在100个单位以内的行(如果字段1匹配):

所需输出:(注意,第三个字段来自文件1中的匹配行)

我尝试使用以下代码:

for i in {1..4} #there are 4 lines in file2
do
chr=$(awk 'NR=="'${i}'" { print $1 }' file2)
pos=$(awk 'NR=="'${i}'" { print $2 }' file2)
gene=$(awk 'NR=="'${i}'" { print $3 }' file2)

start=$(echo $pos | awk '{print $1-100}') #start and end variables for 100 unit range
end=$(echo $pos | awk '{print $1+100}')
awk '{if ($1=="'$chr'" && $2 > "'$start'" && $2 < "'$end'") print "'$chr'","'$pos'","'$gene'"$3}' file1
done
对于{1..4}中的i#文件2中有4行
做
chr=$(awk'NR==“${i}'{print$1}”文件2)
pos=$(awk'NR==“${i}'{print$2}”文件2)
gene=$(awk'NR==“${i}'{print$3}”文件2)
开始=$(echo$pos | awk'{print$1-100}')#100单位范围的开始和结束变量
end=$(echo$pos | awk'{print$1+100}')
awk'{if($1==“$chr'&&$2>”“$start'&&$2<“$end'”)打印“$chr'”、“$pos'”、“$gene'$3}”文件1
完成
代码不起作用,我相信我的start和end变量有问题,因为当我回显$start时,我得到414,这对我来说没有意义,当我回显$end时,我得到614

我理解这个问题可能很难理解,所以如果需要澄清,请询问我


谢谢。

困难在于$1不是唯一的密钥,因此需要注意数据结构以将数据存储在文件1中

使用GNU awk,您可以使用数组的数组:

gawk '
    NR==FNR {f1[$1][$2] = $3; next} 
    $1 in f1 {
        for (val in f1[$1]) 
            if (val-100 <= $2 && $2 <= val+100) 
                print $0, f1[$1][val]
    }
' file1 file2 
gawk'
NR==FNR{f1[$1][$2]=$3;next}
f1一元{
用于(f1中的val[$1])
如果(val-100

pandas是执行此类表格数据操作的正确工具。

您可以在awk中完成这一切,而不是在awk和shell中完成这一切。将第一个文件的内容加载到数组中,然后在循环第二个文件时使用它。如果文件1中的任何一行都有匹配的字段1和小于100的字段2,您想打印文件2中的行吗?什么如果文件1中有多行具有匹配字段1和小于100的字段2?
gawk '
    NR==FNR {f1[$1][$2] = $3; next} 
    $1 in f1 {
        for (val in f1[$1]) 
            if (val-100 <= $2 && $2 <= val+100) 
                print $0, f1[$1][val]
    }
' file1 file2 
awk '
    NR==FNR {f1[$1,$2] = $3; next} 
    {
        for (key in f1) {
            split(key, a, SUBSEP) 
            if (a[1] == $1 && a[2]-100 <= $2 && $2 <= a[2]+100) 
                print $0, f1[key]
        }
    }
' file1 file2 
#!/usr/bin/python

import pandas as pd
from StringIO import StringIO

file1 = """
1 290 rs1345
2 450 rs5313
1 1120 rs4523
2 790 rs4325
"""

file2 = """
1 201 LDLR
2 714 APOA5
1 818 NOTCH5
1 514 TTN
"""

sio = StringIO(file1)
df1 = pd.read_table(sio, sep=" ", header=None)
df1.columns = ["a", "b", "c"]

sio = StringIO(file2)
df2 = pd.read_table(sio, sep=" ", header=None)
df2.columns = ["a", "b", "c"]

df = pd.merge(df2, df1, left_on="a", right_on="a", how="outer")

#query is intuitive
r = df.query("b_y-100 < b_x <b_y + 100")
print r[["a", "b_x", "c_x", "c_y"]]
   a  b_x    c_x     c_y
0  1  201   LDLR  rs1345
7  2  714  APOA5  rs4325