【问题标题】:Substring pattern matching in two files两个文件中的子字符串模式匹配
【发布时间】:2015-04-17 15:32:30
【问题描述】:

我有一个像这样有很多行的输入平面文件:

Apr  3 13:30:02 aag8-ca-acs01-en2 CisACS_01_PassedAuth p1n5ut5s 1 0 Message-Type=Authen OK,User-Name=joe7@it.test.com,NAS-  IP-Address=4.196.63.55,Caller-ID=az-4d-31-89-92-90,EAP Type=17,EAP Type Name=LEAP,Response Time=0,
Apr  3 13:30:02 aag8-ca-acs01-en2 CisACS_01_PassedAuth p1n6ut5s 1 0 Message-Type=Authen OK,User-Name=bobe@jg.test.com,NAS-IP-Address=4.197.43.55,Caller-ID=az-4d-4q-x8-92-80,EAP Type=17,EAP Type Name=LEAP,Response Time=0,
Apr  3 13:30:02 abg8-ca-acs01-en2 CisACS_01_PassedAuth p1n4ut5s 1 0 Message-Type=Authen OK,User-Name=jerry777@it.test.com,NAS-IP-Address=7.196.63.55,Caller-ID=az-4d-n6-4e-y2-90,EAP Type=17,EAP Type Name=LEAP,Response Time=0,
Apr  3 13:30:02 aca8-ca-acs01-en2 CisACS_01_PassedAuth p1n4ut5s 1 0 Message-Type=Authen OK,User-Name=frc777o.@it.test.com,NAS-IP-Address=4.196.263.55,Caller-ID=a4-4e-31-99-92-90,EAP Type=17,EAP Type Name=LEAP,Response Time=0,
Apr  3 13:30:02 aag8-ca-acs01-en2 CisACS_01_PassedAuth p1n4ut5s 1 0 Message-Type=Authen OK,User-Name=frc77@xed.test.com,NAS-IP-Address=4.136.163.55,Caller-ID=az-4d-4w-b5-s2-90,EAP Type=17,EAP Type Name=LEAP,Response Time=0,

我正在尝试 grep 输入文件中的电子邮件地址,以查看它们是否已存在于主文件中。

主平面文件如下所示:

a44e31999290;frc777o.@it.test.com;20150403
az4d4qx89280;bobe@jg.test.com;20150403
0dbgd0fed04t;rrfuf@us.test.com;20150403
28cbe9191d53;rttuu4en@us.test.com;20150403
az4d4wb5s290;frc77@xed.test.com;20150403
d89695174805;ccis6n@cn.test.com;20150403

如果邮件在 master 中不存在,我想要一个简单的计数。

所以使用我希望看到的示例:count=3,因为 bobe@jg.test.comfrc77@xed.test.com 已经存在于 master 中,而其他的则不存在。

我尝试了各种 grep 组合,例如下面来自上次测试的示例,但它不起作用。我在 perl 脚本中使用 grep 来首先捕获电子邮件,然后计算它们,但我真正需要的是来自的电子邮件计数主文件中不存在的输入文件。

grep -o -P '(?<=User-Name=\).*(?=,NAS-IP-)' $infile $mstr > $new_emails;

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: perl grep pattern-matching


    【解决方案1】:

    我会在awk 中使用这种方法:

    $ awk 'FNR==NR {FS=";"; a[$2]; next}
           {FS="[,=]"; if ($4 in a) c++}
           END{print c}' master file
    3
    

    这通过设置不同的字段分隔符和存储/匹配电子邮件来工作。然后,打印最终的总和。

    对于master 文件,我们使用; 并获得第二个字段:

    $ awk -F";" '{print $2}' master 
    frc777o.@it.test.com
    bobe@jg.test.com
    rrfuf@us.test.com
    rttuu4en@us.test.com
    frc77@xed.test.com
    ccis6n@cn.test.com
    

    对于file 文件(包含所有信息的文件),我们使用,= 并获得第4 个字段:

    $ awk -F[,=] '{print $4}' file
    joe7@it.test.com
    bobe@jg.test.com
    jerry777@it.test.com
    frc777o.@it.test.com
    frc77@xed.test.com
    

    【讨论】:

    • 啊,这行得通!非常感谢您解释详细信息 fedorqui,非常感谢。
    【解决方案2】:

    认为下面的内容是你想要的,作为一个带有 diff 和 perl 的衬里:

    diff <( perl -F';' -anE 'say @F[1]' master | sort -u ) <( perl -pe 'm/User-Name=([^,]+),/; $_ = "$1\n"' data | sort -u ) | grep '^>' | perl -pe 's/> //;'
    

    diff &lt;( command_a |sort -u ) &lt;( command_b |sort -u) | grep '&gt;' 让您处理命令输出的设置差异。

    perl -F';' -anE 'say @F[1]' 只是在 ';' 上分割文件的每一行并在自己的行上打印第二个字段。

    perl -pe 'm/User-Name=([^,]+),/; $_ = "$1\n"' 获取您想要忽略周围的 key= 的特定字段并隐式打印在新行上。

    【讨论】:

    • | wc -l 如果你只需要计数;P
    • 感谢马特,它在 cmd 行中也能很好地工作,试图弄清楚如何将其合并到现有的 perl 脚本中以使其工作。
    • 我有这样的,但它抛出一个错误。 diff &lt;( perl -F';' -anE 'say @F[1]' $mstr | sort -u ) &lt;( perl -pe 'm/User-Name=([^,]+),/; $_ = "$1\n"' $infile | sort -u ) | grep '^&gt;' | perl -pe 's/&gt; //;' | wc -l &gt; $outcount; sh: -c: 第 0 行:意外标记附近的语法错误 (' sh: -c: line 0: diff
    • 这肯定不是你在 perl 脚本中所拥有的...... $_ 和 $1 看起来像是在它到达 shell 之前被解释了,所以我猜你有整个东西在后面在你的 perl 脚本中打勾?如果您已经有一个 perl 脚本,为什么不使用几个哈希值在其中正确完成所有这些操作?
    • 是的,我添加了反勾号,我将尝试使用几个哈希值。再次感谢马特。
    猜你喜欢
    • 2017-02-05
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 2014-06-07
    • 2016-11-15
    • 1970-01-01
    相关资源
    最近更新 更多