1

我有两个文件:

文件1.txt

919167,hutch,mumbai
919594,idea,mumbai

文件2.txt

919167000000
919594000000 

输出

919167000000,hutch,mumbai
919594000000,idea,mumbai

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


额外定义

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

扩展数据

文件1.txt

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

文件2.txt

919167838888
919594998484
919212334323

预期输出:

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

3 回答 3

2

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

  1. 公共数字是文件 2 的前 6 位数字(我们不关心尾随数字,而只是将它们复制到输出中)。
  2. 文件按顺序排序。
  3. 如果任一文件中有不匹配的记录,这些记录将被忽略。

选择的工具可能是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命令,该命令连接到第一列,并从 中输出“其余行”(第 2 列)file2.txt和第 2 列和第 3 列file1.txt

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


现在可以获得所需的额外信息。关键信息是 6 位数字是固定的——唷!由于您使用的是 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).


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

文件1.txt

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

文件2.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

于 2012-10-04T05:50:42.050 回答
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
于 2012-10-04T05:55:12.173 回答
0
awk -F, 'FNR==NR{a[$1]=$2","$3;next}{for(i in a){if($1~/i/) print $1","a[i]}}' your_file
于 2012-10-04T09:16:56.503 回答