我已经用 awk 查找了示例,但是在比较多个条件时我很难正确使用数组。我有两个文件,我想在满足两个条件时返回信息:
- 文件 2 的第 1 列(例如 ScYwTfa_25)与文件 1 的第 4 列匹配(即 Y == Y)
- 文件2的第2列大于或等于文件1的第5列但小于或等于文件1的第6列(即Ymin < Y1 < Ymax)
文件 1 中的第 5 列和第 6 列是位置值范围,如果文件 2 的位置在该范围内,我想将其映射到文件 1 的第 2 列和第 3 列中相应的值范围并返回新位置,以及 file1 的第一列。在文件 1 中,第 5 列和第 6 列的范围与第 2 列和第 3 列的范围长度相同,但针对第 4 列和第 1 列中命名的不同坐标系。
以下是示例文件:
文件1
X Xmin Xmax Y Ymin Ymax
10 27124 27153 ScYwTfa_25 11382070 11382099
10 41731 41779 ScYwTfa_10450 20433584 20433632
10 41780 41819 ScYwTfa_10450 20433544 20433583
10 41886 41916 ScYwTfa_10450 20433447 20433477
10 41917 41943 ScYwTfa_10450 20433420 20433446
文件2
Y Y1
ScYwTfa_25 11382075
ScYwTfa_10450 20433425
ScYwTfa_10450 20433430
ScYwTfa_10450 99999999
期望的结果是:
10 27129
10 41922
10 41927
产生结果的第一行是因为ScYwTfa_25文件 2 匹配的ScYwTfa_25在文件 1 AND 11382075(文件 2)中,其范围为 11382070 到 11382099(文件 1)。因此,文件 1 的第 1 列被打印(即 10),并且 27129 是基于从第 2 列和第 3 列在文件 1 中的新范围中查找 11382075 的位置(即 Xmin + (Y1 - Ymin) = 27124 + (11382075 - 11382070) = 27129)。
同样,文件 2 的第 2 行和第 3 行对应于文件 1 的最后一行,因此会产生输出。但是,文件 2 中的最后一行不会产生任何输出,因为即使 ScYwTfa_10450 在文件 1 中具有多个匹配项,位置 99999999 也不在该 Y 的任何 Ymin 到 Ymax 的范围内。
希望这个例子能够很好地解释它。尽管我一直在尝试使用 NR == FNR 方法,但我没有太多使用 awk 来关联不同文件之间的信息。
提前致谢,
马特
答案1
awk '
FNR==1{ next } # skip header on file2, file1
FNR==NR{ # if file2...
y[$1]=(y[$1]=="" ? "" : y[$1] FS) $2 # append Y1-values FS-separated to array `y`
next # continue with next record
}
# if file1...
($4 in y){ # col4 matches col1 of file2
n=split(y[$4], y1) # split Y1-values into array `y1`
# of length n (using FS as separator)
for (i=1;i<=n;i++) # loop over y1 values
if ($5<=y1[i] && y1[i]<=$6) # Y1 in range?
print $1, ($2 + (y1[i] - $5)) # print result
}
' file2 file1