使用awk和打印比较两个文件包含与其他文件匹配的文件

时间:2012-10-04 05:31:24

标签: linux awk

我有两个文件:

FILE1.TXT

919167,hutch,mumbai
919594,idea,mumbai

FILE2.TXT

919167000000
919594000000 

输出

919167000000,hutch,mumbai
919594000000,idea,mumbai

如何使用AWK实现这一目标?我有一个庞大的电话号码文件需要像这样比较。我相信Awk可以处理它;如果没有,请让我知道我该怎么做。


额外定义

  • 公共部分总是一个6位数字吗?是的总是6。
  • 两个文件是否已排序? file1未排序。 file2可以排序。
  • 文件2中的尾随数字是否始终为零?不,这些是可能不同的电话号码,目的是获取电话号码的系列信息。
  • 文件1是否包含给定数字的三个记录,而文件2包含2个记录,或者它是一对一的?它是一对一的。 文件1中是否有记录,文件2中没有匹配,反之亦然?_是。
  • 如果是,您要查看不匹配的记录吗?是的我想要两个记录。

扩展数据

FILE1.TXT

919167,hutch,mumbai
919594,idea,mumbai
918888,airtel,karnataka

FILE2.TXT

919167838888
919594998484
919212334323

预期输出:

919167838888,hutch,mumbai
919594998484,idea,mumbai
919212334323,nomatch,nomatch

3 个答案:

答案 0 :(得分:2)

正如我在评论中所指出的那样,需要提供大量未说明的信息才能给出明确的答案。但是,我们可以做出一些看似合理的猜测:

  1. 常用数字是文件2的前6位数字(我们不关心尾随数字,但只是将它们复制到输出中)。
  2. 文件按顺序排序。
  3. 如果两个文件中都有不匹配的记录,那么这些记录将被忽略。
  4. 选择的工具可能是sedjoin

    sed 's/^\([0-9]\{6\}\)/\1,\1/' file2.txt |
    join -t, -o 1.2,2.2,2.3 - file1.txt
    

    这会编辑file2.txt以创建逗号分隔的第一个字段,其中包含6位数的电话号码,然后是该行的其余部分。输入被输入join命令,该命令连接到第一列,并输出file2.txt的“其余部分”(第2列)以及file1.txt的第2列和第3列

    如果电话号码是可变长度的,那么匹配操作非常复杂。为此,我将进入Perl(或Python)来完成工作。如果数据未排序,则可以在输入命令之前对其进行排序。如果您想要不匹配的记录,可以指定如何处理join的选项中的那些。


    现在可以获得所需的额外信息。关键信息是固定的6位数 - p!由于您使用的是Linux,我假设bash可用“进程替换”:

    sort file2.txt |
    sed 's/^\([0-9]\{6\}\)/\1,\1/' |
    join -t, -o 1.2,2.2,2.3 -a 1 -a 2 -e 'no-match' - <(sort file1.txt)
    

    如果没有流程替换,只需在原地排序file1.txt

    sort -o file1.txt file1.txt
    

    然后使用file1.txt代替<(sort file1.txt)


    我认为评论可能会要求输入,例如:

    FILE1.TXT

    919167,hutch,mumbai
    919594,idea,mumbai
    902130,airtel,karnataka
    

    FILE2.TXT

    919167000000
    919594000000
    919342313242
    

    输出

    no-match,airtel,karnataka
    919167000000,hutch,mumbai
    919342313242,no-match,no-match
    919594000000,idea,mumbai
    

    如果这不是评论的内容,请通过编辑问题来澄清,以便以比评论允许的更易读的格式添加额外的数据和输出。


    使用扩展数据,这个经过温和修改的命令:

    sort file2.txt |
    sed 's/^\([0-9]\{6\}\)/\1,\1/' |
    join -t, -o 1.2,2.2,2.3 -a 1 -e 'no-match' - <(sort file1.txt)
    

    产生输出:

    919167838888,hutch,mumbai
    919212334323,no-match,no-match
    919594998484,idea,mumbai
    

    看起来更像是所需输出的排序版本。 -a n选项控制是否打印来自文件1或文件2(或两者)的不匹配记录; -e选项控制为不匹配的字段打印的值。当然,所有这些都可以从join的手册页中获得。

答案 1 :(得分:2)

这是使用GNU awk的单向方式。像:

一样运行
awk -f script.awk file2.txt file1.txt

script.awk的内容:

BEGIN {
    FS=OFS=","
}

FNR==NR {
    sub(/[ \t]+$/, "")
    line = substr($0, 0, 6)
    array[line]=$0
    next
}

{
    printf ($1 in array) ? $0"\n" : "FILE1 no match --> "$0"\n"
    dup[$1]++
}

END {
    for (i in array) {
        if (!(i in dup)) {
            printf "FILE2 no match --> %s\n", array[i]
        }
    }
}

或者,这里是单行:

awk 'BEGIN { FS=OFS="," } FNR==NR { sub(/[ \t]+$/, ""); line = substr($0, 0, 6); array[line]=$0; next } { printf ($1 in array) ? $0"\n" : "FILE1 no match --> "$0"\n"; dup[$1]++} END { for (i in array) if (!(i in dup)) printf "FILE2 no match --> %s\n", array[i] }' file2.txt file1.txt

答案 2 :(得分:0)

awk -F, 'FNR==NR{a[$1]=$2","$3;next}{for(i in a){if($1~/i/) print $1","a[i]}}' your_file