awk改进命令打印匹配和不匹配案例:

时间:2014-08-13 12:44:14

标签: awk

想要阅读并比较两个文件中的第一个字段然后打印

  1. 匹配两个文件中的行 - (在f11.txt和f22.txt中可用) - > Op_Match.txt
  2. 来自f11.txt的非匹配行(f11.txt中可用的f11.txt中不可用) - > Op_NonMatch_f11.txt
  3. 来自f22.txt的非匹配行(f22.txt中可用的f22.txt中不可用) - > Op_NonMatch_f22.txt
  4. 使用以下3个单独的命令来实现上述场景。

    f11.txt

    10,03-APR-14,abc
    20,02-JUL-13,def
    10,19-FEB-14,abc
    20,02-AUG-13,def
    10,22-JAN-07,abc
    10,29-JUN-07,abc
    40,11-SEP-13,ghi
    

    f22.txt

    50,DL,3000~4332,ABC~XYZ
    10,DL,5000~2503,ABC~XYZ
    30,AL,2000~2800,DEF~PQZ
    

    匹配两个文件中的行:

    awk ' BEGIN {FS = OFS = ","} FNR==NR {a[$1] = $0; next} ($1 in a) {print $0,a[$1]}'   f22.txt f11.txt> Op_Match.txt
    
    10,03-APR-14,abc,10,DL,5000~2503,ABC~XYZ
    10,19-FEB-14,abc,10,DL,5000~2503,ABC~XYZ
    10,22-JAN-07,abc,10,DL,5000~2503,ABC~XYZ
    10,29-JUN-07,abc,10,DL,5000~2503,ABC~XYZ
    

    来自f11.txt的非匹配行:

    awk ' BEGIN {FS = OFS = ","} FNR==NR {a[$1] = $0; next} !($1 in a) {print $0}'   f22.txt f11.txt > Op_NonMatch_f11.txt
    
    20,02-JUL-13,def
    20,02-AUG-13,def
    40,11-SEP-13,ghi
    

    来自f22.txt的非匹配行:

    awk ' BEGIN {FS = OFS = ","} FNR==NR {a[$1] = $0; next} !($1 in a) {print $0}'   f11.txt f22.txt > Op_NonMatch_f22.txt
    
    50,DL,3000~4332,ABC~XYZ
    30,AL,2000~2800,DEF~PQZ
    

    使用以上3个单独的命令来实现上述场景。有没有最简单的方法来避免3种不同的命令?任何建议...... !!!

3 个答案:

答案 0 :(得分:1)

这样的事情,未经测试:

awk '
BEGIN{ FS=OFS="," }
NR==FNR {
    fname1 = FILENAME
    keys[NR] = $1
    recs[NR] = $0
    key2nrs[$1] = ($1 in key2nrs ? key2nrs[$1] RS : "") NR
    next
}
{
    if ($1 in key2nrs) {
        split (key2nrs[$1],nrs,RS)
        for (i=1; i in nrs; i++) {
            print recs[nrs[i]], $0 > "Op_Match.txt"
        }
        matched[$1]
    }
    else {
        print > ("Op_NonMatch_" FILENAME ".txt")
    }
}
END {
    for (i=1; i in recs; i++) {
        if (! (keys[i] in matched) ) {
            print recs[i] > ("Op_NonMatch_" fname1 ".txt")
        }
    }
}
' f11.txt f22.txt

这与Kent和Etans的答案之间的主要区别在于他们认为f22.txt中的$ 1只能在该文件中出现一次,而如果10作为第一个字段出现,则上述内容将起作用在多行f22.txt。

另一个不同之处在于上面的输出行与它们在输入文件中出现的顺序相同,而其他答案将根据它们在内部存储在散列表中的方式以随机顺序输出其中的一些。 / p>

答案 1 :(得分:0)

这里有一个:

awk -F, -v OFS="," 'NR==FNR{a[$1]=$0;next}
    $1 in a{print $0,a[$1]>("common.txt");c[$1];next} 
    {print $0>("NonMatchFromFile1.txt")}                     
    END{for(x in a)
        if(!(x in c)) 
            print a[x]>("NonMatchFromFile2.txt")}' f2 f1     

有了这个,你将获得3个文件:common.txt, nonmatchfromFile1.txt and nonMatchfromfile2.txt

答案 2 :(得分:0)

我还没有检查过@ EdMorton的答案,但他很可能已经做对了。

我的解决方案(看起来比他乍看之下略显普遍)是:

awk -F, '
FNR==NR {
    a[$1]=$0;
    next
}
($1 in a){
    print $0,a[$1] > "Op_Match.txt"
    am[$1]++
}
!($1 in a) {
    print $0 > "Op_NonMatch_f11.txt"
}
END {
    for (i in a) {
        if (!(i in am)) {
            print a[i] > "Op_NonMatch_f22.txt"
        }
    }
}
' f22.txt f11.txt