Awk不会将字段识别为整数值

时间:2016-01-27 16:16:31

标签: bash awk filter

我正在尝试根据另一列的两列过滤一个文件。 问题是[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]])没有区分,例如,区间70083 83083,位置7323573(请参见下文)。 目的是检索文件2的第5列中的文件1的值。 文件1在列3 ex:51476中只有一个位置,文件2具有由列3和4表示的间隔。 最后,我需要文件1具有第5列的相应值(参见输出)。

档案1

awk

文件2

rs187298206 chr1 51476 0.0072 0.201426626822702
rs116400033 chr1 51479 0.2055 1.18445621536109
rs62637813 chr1 52058 0.0587 0.551216300225955
rs190291950 chr1 52144 -4e-04 0.036575951491895
rs150021059 chr1 52238 0.3325 1.70427928591544
rs140052487 chr1 54353 0.003 0.12778378962414
rs146477069 chr1 54421 0.1419 0.924336309646664
rs141149254 chr1 54490 0.1767 1.06786868821145
rs2462492 chr1 54676 0.0819 0.664355314594874
rs143174675 chr1 54753 0.026 0.356836206987615
rs3091274 chr1 55164 0.3548 1.80091078751368
rs10399749 chr1 55299 0.0309 0.389748348495465
rs182462964 chr1 55313 2e-04 0.0877969207975495
rs3107975 chr1 55326 0.0237 0.344080010917931
rs142800240 chr1 7323573 -6e-04 0.0361473609720785

我用这个脚本得到了什么:

51083_1 chr1 51083 56000 -0.177152387075888 0.172569306719619
57083_1 chr1 57083 60083 -0.0524335467819781 0.130497858911419
60083_1 chr1 70083 83083 -0.0332555672564894 0.124932838766226
525083_1 chr1 525083 528083 0.291406335374442 0.0577249392691202
528083_1 chr1 528083 531083 0.291406335374442 0.0577249392691202
531083_1 chr1 531083 534083 0.291406335374442 0.0577249392691202
534083_1 chr1 534083 537083 0.291406335374442 0.0577249392691202
534083_1 chr1 534083 537083 0.441406335374442 0.0577249392691202

输出

awk '
NR == FNR {score[$3] = $1 FS $2 FS $3 FS $4; next}
{
for (key in score)
if (key > $3 && key < $4)
print score[key], $5
}
' file1 file2 > output

2 个答案:

答案 0 :(得分:2)

awk '     
NR == FNR {score[$3] = $1 FS $2 FS $3 FS $4; next}
{
for (key in score)
if (key+0 > $3 && key+0 < $4)
print score[key], $5
}
' fst.txt tajima.txt > output

给了我

[/tmp]$ cat output
rs182462964 chr1 55313 2e-04 -0.177152387075888
rs190291950 chr1 52144 -4e-04 -0.177152387075888
rs62637813 chr1 52058 0.0587 -0.177152387075888
rs146477069 chr1 54421 0.1419 -0.177152387075888
rs140052487 chr1 54353 0.003 -0.177152387075888
rs3107975 chr1 55326 0.0237 -0.177152387075888
rs187298206 chr1 51476 0.0072 -0.177152387075888
rs141149254 chr1 54490 0.1767 -0.177152387075888
rs10399749 chr1 55299 0.0309 -0.177152387075888
rs3091274 chr1 55164 0.3548 -0.177152387075888
rs143174675 chr1 54753 0.026 -0.177152387075888
rs2462492 chr1 54676 0.0819 -0.177152387075888
rs150021059 chr1 52238 0.3325 -0.177152387075888
rs116400033 chr1 51479 0.2055 -0.177152387075888

强制将解释作为数字,将0添加到其中。来自awk的手册页。

答案 1 :(得分:1)

我可以使用系统的BSD awk在Mac OS X 10.11.3上重现您的问题。

问题在于字符串与数字比较; awk似乎将key视为字符串,并且正在进行字符串比较而不是数字比较。

我粗暴地强迫它用数字处理比较:

awk '
NR == FNR {score[$3] = $1 FS $2 FS $3 FS $4; next}
{
    for (key in score)
    {
        if (key+0 > $3+0 && key+0 < $4+0)
        {
            #print "==", key, $3, $4
            #if (key > $3) print key, ">", $3
            #if (key < $4) print key, "<", $4
            print score[key], $5
        }
    }
}
' file1 file2

您可以看到“+0”强制awk将内容视为数字。 (强制awk将值视为字符串的类似物是,例如key "",它将空字符串连接到key的(字符串)值。)

根据您的样本数据,我得到输出:

rs140052487 chr1 54353 0.003 -0.177152387075888
rs150021059 chr1 52238 0.3325 -0.177152387075888
rs3107975 chr1 55326 0.0237 -0.177152387075888
rs3091274 chr1 55164 0.3548 -0.177152387075888
rs187298206 chr1 51476 0.0072 -0.177152387075888
rs116400033 chr1 51479 0.2055 -0.177152387075888
rs10399749 chr1 55299 0.0309 -0.177152387075888
rs146477069 chr1 54421 0.1419 -0.177152387075888
rs190291950 chr1 52144 -4e-04 -0.177152387075888
rs182462964 chr1 55313 2e-04 -0.177152387075888
rs141149254 chr1 54490 0.1767 -0.177152387075888
rs62637813 chr1 52058 0.0587 -0.177152387075888
rs143174675 chr1 54753 0.026 -0.177152387075888
rs2462492 chr1 54676 0.0819 -0.177152387075888

让游戏消失的部分调试输出是:

== 54676 51083 56000
54676 > 51083
54676 < 56000
rs2462492 chr1 54676 0.0819 -0.177152387075888
== 7323573 70083 83083
7323573 > 70083
7323573 < 83083
rs142800240 chr1 7323573 -6e-04 -0.0332555672564894

对于5位数字符串,比较恰好与数字比较相同。对于另一个,它没有。我还应该指出,$3+0$4+0部分可能不是必需的。当我显示调试输出时,我有那些 - 但是当我将0添加到key时,测试才开始起作用。因此,我可能不需要将0添加到$3$4