两个文件,两个字段匹配并替换为新文件

时间:2014-04-15 17:08:10

标签: awk substitution

跑进脑筋,正在寻求指导/小费。我有两个文件,我需要检查两个字段的值,比较它们,如果匹配,将它们扔到第三个文件中:

文件一:

tail -n 1 file_A

09/03/2013:11:55:49 S 7187187187@2.3.4.5 9999999@6.7.8.9 ThisPlace:Washington 0 09/03/2013:12:05:27 578

文件二:

head -n 2 file_B
7187187187,"OfficeA"
9999999,"OfficeB"

期望的结果:

more desired_result
09/03/2013:11:55:49 S 7187187187@OfficeA 9999999@OfficeB ThisPlace:Washington 0 09/03/2013:12:05:27 578

我想到了在每个实例上匹配的循环中的shell脚本,但我确信有一种方法可以使用awk匹配两个字段。

awk -F"@" 'NR==FNR{a[$1]=$2;next}{if ($2 in a)print a[$2]";"$0}'  fileA fileB 

不,我已经尝试了各种差异ORS,FS,NR组合到我难倒的地方,我确信我忽略了什么

EDITED

@jotne

$ more fileA
08/22/2013:09:21:33 E 9876543210@10.25.50.33 3333444488@10.100.10.3 EProv:EastProvidence_RI 1 08/22/2013:09:21:33 0
09/03/2013:05:09:58 S 5556666777@10.30.239.18 8877887788@10.50.25.1 Tacoma:Washington 0 09/03/2013:13:29:31 29973
09/03/2013:10:46:19 S 3333444488@10.11.12.13 7777777777@10.17.19.2 Boston:MA 0 09/03/2013:12:01:28 4509
09/03/2013:10:49:54 S 1111122222@10.20.30.1 99999888888@10.20.30.1 Gaith:MD 0 09/03/2013:12:09:26 4772
09/03/2013:10:49:54 S 1111122222@10.20.30.1 57778889999@10.20.30.1 Balt:MD 1 09/03/2013:12:09:26 4772

$ more fileB
3333444488,"Providence_Route"
5556666777,"Kenosha_Route"
9999988888,"Chitown_Route"
7778889999,"Chitown_Route"

这是它的要点。这些是我想要匹配的电话号码(CDR)。我在fileB中列出的数字结构为:

telnumber,"Which_Session_Border_Controller_Its_Routing_Through"

我想说:在fileA中查找所有这些数字:看看fileB,如果你看到fileA的3美元或4美元替换匹配路线名称@符号之后的任何内容。

虽然对我来说似乎更容易perl -pi -e 's:10.20.30.1:ChitownRoute:g' fileA我使用的地址已经过消毒和波动,所以即使尝试修复这些地址本身也很令人头痛。我会发布更多的例子,但fileA是1GB,fileB有大约44k行

2 个答案:

答案 0 :(得分:1)

试试这个:

awk -F'[, ]' '
NR==FNR{
    gsub(/\"/,"",$2);
    a[$1]=$2; 
    next
}   
{
    split($3,t,/@/);
    $3=t[1]"@"a[t[1]];
    split($4,t,/@/);
    $4=t[1]"@"a[t[1]]
}1' fileb filea
09/03/2013:11:55:49 S 7187187187@OfficeA 9999999@OfficeB ThisPlace:Washington 0 09/03/2013:12:05:27 578

答案 1 :(得分:0)

以下是awk版本:

awk 'FNR==NR {split($1,f,"[,\"]");a[f[1]]=f[3];next} {for (i in a) for (j=1;j<=NF;j++) if ($j~i) $j=i"@"a[i]}1' fileB fileA
09/03/2013:11:55:49 S 7187187187@OfficeA 9999999@OfficeB ThisPlace:Washington 0 09/03/2013:12:05:27 578

此解决方案将循环遍历fileA中的所有元素,并针对fileB中的数据进行测试。

更具可读性:

awk '
FNR==NR {
    split($1,f,"[,\"]")
    a[f[1]]=f[3]
    next} 

    {
    for (i in a)
        for (j=1;j<=NF;j++)
            if ($j~i)
                $j=i"@"a[i]
        }
1
' fileB fileA

使用fileA

09/03/2013:11:55:49 S 7187187187@2.3.4.5 9999999@6.7.8.9 ThisPlace:Washington 0 09/03/2013:12:05:27 578

fileB

7187187187,"OfficeA"
9999999,"OfficeB"

这给出了:

09/03/2013:11:55:49 7187187187@OfficeA 9999999@OfficeB ThisPlace:Washington 0 09/03/2013:12:05:27 578

新文件的结果:

08/22/2013:09:21:33 E 9876543210@10.25.50.33 3333444488@Providence_Route EProv:EastProvidence_RI 1 08/22/2013:09:21:33 0
09/03/2013:05:09:58 S 5556666777@Kenosha_Route 8877887788@10.50.25.1 Tacoma:Washington 0 09/03/2013:13:29:31 29973
09/03/2013:10:46:19 S 3333444488@Providence_Route 7777777777@10.17.19.2 Boston:MA 0 09/03/2013:12:01:28 4509
09/03/2013:10:49:54 S 1111122222@10.20.30.1 9999988888@Chitown_Route Gaith:MD 0 09/03/2013:12:09:26 4772
09/03/2013:10:49:54 S 1111122222@10.20.30.1 7778889999@Chitown_Route Balt:MD 1 09/03/2013:12:09:26 4772