awk hash 在两个输入文件上应用条件
awk hash applying conditions on two input files
我正在尝试使用 awk
比较两个文件,我想根据三个条件将它们合并。
- 第 2 列等于第 1 列
- 第 3 列大于或等于第 2 列
- 第 3 列小于或等于第 3 列
文件如下所示:
文件 1
snp1 14 6371334
snp2 14 7928189
snp3 14 31819743
snp4 14 62133529
snp5 14 62616434
snp6 14 17544926
snp7 14 31639444
文件 2
14 71159186 72228540 31
14 15732809 16677121 68
14 45003977 46299534 69
14 61965465 64286878 128
14 17378950 17833828 141
14 12877549 13217565 193
14 31369019 31785149 194
14 49883707 49905143 197
所需的输出将是:
snp1 14 6371334 0
snp2 14 7928189 0
snp3 14 31819743 0
snp4 14 62133529 128
snp5 14 62616434 128
snp6 14 17544926 141
snp7 14 31639444 194
我试过这个:
awk 'NR==FNR {a[]=;b[]=;c[]=;d[]=;next} {if( in a && >= b[] && <= c[]) print ,,,d[]}' file2 file1
但不是这样的。
有什么帮助吗?
谢谢!
看起来你可能想为 snp 分配一个间隔
也就是说,如果一个 snp 在某个区间内
报告与间隔关联的标识符。
我几乎不喜欢看到的东西包括 NR==FNR
模式的使用
没有相应的 NR!=FNR
模式。
四个独立数组的想法,其中每个键都是其值的副本
...你能用它做什么?
同一行中的任何项目无论如何都不会偶然保存。
不是说你应该这样做...
但是您可能会想的是,使用以下结构可以更好地满足您的需求:
a[NR]=;b[NR]= ....
在同一行上相关的项目可以这样恢复
第一个块中的尾随 ;next
可能没有任何帮助
因为 awk 的自然行为是在没有被告知的情况下继续进行。
第二块尚未包含 awk 的本质...
条件在块
之前隐含
类似
NR != FNR && in a ... {print ...
如果可能的话,您通常首先想要小得多的文件
然后流过第二个,特别是如果第二个大得多。
注意:您的样本似乎具有未被利用的顺序
大纲可能看起来像
read file1 into array(s) maintaining order
process first item from file1 through file2 until
found OR not exists is determined.
proceed to process next item from file1 (continuing from where you are in file2)
rinse & repeat
我可以为你做你的工作,但你会得到更好的服务
考虑一些
,你自己再考虑一下运行
提出的观点
如果您再次遇到困难,请 post 您更接近的近似值
可能有用的东西,我会回来查看。
对于数组的数组使用 GNU awk 并假设值只能在给定键的 1 个范围内:
$ cat tst.awk
NR==FNR {
ranges2vals[][ FS ] =
next
}
{ val = 0 }
in ranges2vals {
for (range in ranges2vals[]) {
split(range,r)
if ( (r[1] <= ) && ( <= r[2]) ) {
val = ranges2vals[][range]
break
}
}
}
{ print [=10=], val }
$ awk -f tst.awk file2 file1
snp1 14 6371334 0
snp2 14 7928189 0
snp3 14 31819743 0
snp4 14 62133529 128
snp5 14 62616434 128
snp6 14 17544926 141
snp7 14 31639444 194
我正在尝试使用 awk
比较两个文件,我想根据三个条件将它们合并。
- 第 2 列等于第 1 列
- 第 3 列大于或等于第 2 列
- 第 3 列小于或等于第 3 列
文件如下所示:
文件 1
snp1 14 6371334
snp2 14 7928189
snp3 14 31819743
snp4 14 62133529
snp5 14 62616434
snp6 14 17544926
snp7 14 31639444
文件 2
14 71159186 72228540 31
14 15732809 16677121 68
14 45003977 46299534 69
14 61965465 64286878 128
14 17378950 17833828 141
14 12877549 13217565 193
14 31369019 31785149 194
14 49883707 49905143 197
所需的输出将是:
snp1 14 6371334 0
snp2 14 7928189 0
snp3 14 31819743 0
snp4 14 62133529 128
snp5 14 62616434 128
snp6 14 17544926 141
snp7 14 31639444 194
我试过这个:
awk 'NR==FNR {a[]=;b[]=;c[]=;d[]=;next} {if( in a && >= b[] && <= c[]) print ,,,d[]}' file2 file1
但不是这样的。
有什么帮助吗?
谢谢!
看起来你可能想为 snp 分配一个间隔
也就是说,如果一个 snp 在某个区间内
报告与间隔关联的标识符。
我几乎不喜欢看到的东西包括 NR==FNR
模式的使用
没有相应的 NR!=FNR
模式。
四个独立数组的想法,其中每个键都是其值的副本
...你能用它做什么?
同一行中的任何项目无论如何都不会偶然保存。
不是说你应该这样做...
但是您可能会想的是,使用以下结构可以更好地满足您的需求:
a[NR]=;b[NR]= ....
在同一行上相关的项目可以这样恢复
第一个块中的尾随 ;next
可能没有任何帮助
因为 awk 的自然行为是在没有被告知的情况下继续进行。
第二块尚未包含 awk 的本质...
条件在块
类似
NR != FNR && in a ... {print ...
如果可能的话,您通常首先想要小得多的文件 然后流过第二个,特别是如果第二个大得多。
注意:您的样本似乎具有未被利用的顺序
大纲可能看起来像
read file1 into array(s) maintaining order
process first item from file1 through file2 until
found OR not exists is determined.
proceed to process next item from file1 (continuing from where you are in file2)
rinse & repeat
我可以为你做你的工作,但你会得到更好的服务
考虑一些
,你自己再考虑一下运行
提出的观点
如果您再次遇到困难,请 post 您更接近的近似值
可能有用的东西,我会回来查看。
对于数组的数组使用 GNU awk 并假设值只能在给定键的 1 个范围内:
$ cat tst.awk
NR==FNR {
ranges2vals[][ FS ] =
next
}
{ val = 0 }
in ranges2vals {
for (range in ranges2vals[]) {
split(range,r)
if ( (r[1] <= ) && ( <= r[2]) ) {
val = ranges2vals[][range]
break
}
}
}
{ print [=10=], val }
$ awk -f tst.awk file2 file1
snp1 14 6371334 0
snp2 14 7928189 0
snp3 14 31819743 0
snp4 14 62133529 128
snp5 14 62616434 128
snp6 14 17544926 141
snp7 14 31639444 194