awk匹配并找到文件和输出结果之间的不匹配

时间:2016-08-27 13:17:28

标签: awk

在下面awk我使用$5 $7$8 file1来搜索$3 $5和{ {1}}的{​​1}}。跳过标题行,然后输出一个新文件,其中包含哪些行匹配,如果它们与匹配所缺少的$6不匹配。当我搜索一个匹配时,使用3个字段作为查找的键,不要跳过标题我得到file2。我为长篇文章和file道歉,只是试图包含所有内容以帮助实现这一目标。谢谢你:)。

文件1

current output

file2的

file examples

AWK

 Index  Chromosomal Position    Gene    Inheritance Start   End Ref Alt Func.refGene
98  48719928    FBN1    AD  48719928    48719929    AT  -   exonic
101 48807637    FBN1    AD  48807637    48807637    C   T   exonic

当前输出

R_Index Chr Start   End Ref Alt Func.IDP.refGene
36  chr15   48719928    48719929    AT  -   exonic
37  chr15   48719928    48719928    A   G   exonic
38  chr15   48807637    48807637    C   T   exonic

所需的输出

awk -F'\t' '
    NR == FNR {
            A[$25]; A[$26]; A[$27]
            next
    }
    {
            B[$3]; B[$5]; B[$6]
    }
    END {
            print "Match"
            OFS=","
            for ( k in A )
            {
                    if ( k && k in B )
                            printf "%s ", k
            }

            print "Missing from file1"
            OFS=","
            for ( k in B )
            {
                    if ( ! ( k in A ) )
                            printf "%s ", k
            }

            print "Missing from file2"
            OFS=","
            for ( k in A )
            {
                    if ( ! ( k in B ) )
                            printf "%s ", k
            }
    }
' file1 file2 > list

2 个答案:

答案 0 :(得分:2)

你误解了awk语法并且将awk与shell混淆。当你写道:

A[$25] [$26] [$27]
你可能意味着:

A[$25]; A[$26]; A[$27]

(同样适用于B[])以及当你写下:

IFS=

因为IFS是一个shell变量,而不是一个awk,你可能意味着

FS=

但是,因为你在END部分执行此操作并且没有调用split(),所以没有做任何使用FS idk的事情,而你希望用它来实现。也许你的意思是:

OFS=

但是你没有做任何会使用OFS的事情,而你想要的输出也不是以逗号分隔的,所以你希望用它来实现这一点。

如果这还不足以让您自己解决问题,那么请将您的示例缩减为10列或更少的内容,以便我们不必阅读大量无关信息来帮助您。

答案 1 :(得分:1)

计划1

除非输出格式与您请求的格式不同,否则此方法有效:

awk 'FNR==1 { next }
     FNR == NR { file1[$5,$7,$8] = $5 " " $7 " " $8 }
     FNR != NR { file2[$3,$5,$6] = $3 " " $5 " " $6 }
     END { print "Match:"; for (k in file1) if (k in file2) print file1[k] # Or file2[k]
           print "Missing in file1:"; for (k in file2) if (!(k in file1)) print file2[k]
           print "Missing in file2:"; for (k in file1) if (!(k in file2)) print file1[k]
     }' file1 file2

输出1

Match:
48807637 C T
48719928 AT -
Missing in file1:
48719928 A G
Missing in file2:

计划2

如果您必须在一行中以逗号分隔的类别中包含每组值,则:

awk 'FNR==1 { next }
     FNR == NR { file1[$5,$7,$8] = $5 " " $7 " " $8 }
     FNR != NR { file2[$3,$5,$6] = $3 " " $5 " " $6 }
     END {
            printf "Match"
            pad = " "
            for (k in file1)
            {
                if (k in file2)
                {
                    printf "%s%s", pad, file1[k]
                    pad = ", "
                }
            }
            print ""

            printf "Missing in file1"
            pad = " "
            for (k in file2)
            {
                if (!(k in file1))
                {
                    printf "%s%s", pad, file2[k]
                    pad = ", "
                }
            }
            print ""

            printf "Missing in file2"
            pad = " "
            for (k in file1)
            {
                if (!(k in file2))
                {
                    printf "%s%s", pad, file1[k]
                    pad = ", "
                }
            }
            print ""
     }' file1 file2

代码有点大,但使用的格式加剧了差异。更改全部在END块中;其他代码没有变化。 END块中的动作序列不再舒适地放在一条线上,因此它们是为了便于阅读而展开。如果需要,您可以应用自由的少数分号并连接这些行来缩小程序的表观大小。

尝试打印功能很诱人,但条件只是让它变得太棘手而不值得,我想 - 但我会接受说服的说法。

输出2

Match 48807637 C T, 48719928 AT -
Missing in file1 48719928 A G
Missing in file2

此输出将比首先显示的输出难以解析,因此使用它自动执行任何操作都会非常棘手。虽然只需要担心3个条目,但行长度不是问题。如果您获得300万条记录,那么这些线条会变得非常长且无法管理。