根据其中一个字段内的部分子字符串匹配打印多个字段

根据其中一个字段内的部分子字符串匹配打印多个字段

从这个数据来看:

"STRING1","c45621396a774a7a79b095a1b73b1d3b","2016-04-14T19:39:41.529978","1.0.4.4","7-sp1.0-amd64","","10.224.241.219|0.0.0.0|0.0.0.0|192.168.0.6|0.0.0.0"
"STRING2","c5815139f3051de2ab67909b03a01203","2016-04-14T19:37:47.991569","1.0.4.4","7-sp1.0-amd64","","10.230.16.188"
"STRING3","c837513923e2abfe4df41c2240d1c869","2016-04-14T19:40:10.385759","1.0.4.4","7-sp1.0-amd64","","0.0.0.0|0.0.0.0|0.0.0.0|10.226.41.43"
"STRING4","c837544923e2abfe4df41c2240d1c869","2016-04-14T19:40:10.385779","1.0.4.4","7-sp0.0-amd64","","8.8.8.8|0.0.0.0|0.0.0.0|0.0.0.0|10.226.41.43"
"STRING5","c837544003e2abfe4df41c2240d1c869","2016-04-14T19:40:10.382379","1.0.4.4","7-sp0.0-amd64","","0.0.0.0|10.20.40.6|0.0.0.0|10.226.41.43"

我只愿保留

  • 第一个字段(这是一个具有不可预测的字母数字/长度的字符串)和
  • 从第六字段开始,只有以10开头的IP地址(可能有一个或多个)。

根据下面的示例,这是所需的输出:

STRING1 10.224.241.219
STRING2 10.230.16.188
STRING3 10.226.41.43
STRING4 10.226.41.43
STRING5 10.20.40.6 10.226.41.43

sed/awk 有何魔力可以实现这一目标?我可以使用 GNU/Linux 系统或 cygwin 上的任何标准文本处理实用程序来实现此目的。

谢谢

答案1

如果您的字段从不包含逗号,您可以尝试:

$ perl -F, -lane '@k=split(/["|]/,$F[6]); 
                  @l=grep{/^10\./}@k; 
                  print "$F[0] @l"' file | 
    sed 's/"//g'
STRING1 10.224.241.219
STRING2 10.230.16.188
STRING3 10.226.41.43
STRING4 10.226.41.43
STRING5 10.20.40.6 10.226.41.43

解释

Perl 的-a选项使其工作方式类似于awk,它将根据给定的值拆分其输入文件-F,并将每个结果字段保存为数组中的元素@F。因此,第一个字段将是$F[0],第二个字段$F[1]等。该选项向每个调用-l添加一个换行符,并告诉您逐行读取其输入文件并将 给定的脚本应用于每行。print-nperl-e

  • @k=split(/["|]/,$F[6]);:将第 7 个字段拆分为"|并将其保存为数组@k。这将是 IP。
  • @l=grep{/^10\./}@k;:保存数组中@k以 a 开头的所有字段。10@l
  • print "$F[0] @l":打印第一个字段以及 中的任何内容@l
  • sed 's/"//g': 删除引号。由于perl将在运行其他任何操作之前分割输入行,因此使用另一个程序更容易。

您还可以通过不使用临时数组变量来缩短 Perl 脚本:

perl -F, -lane 'print "$F[0] ", join " ", grep{/^10\..*/} split(/["|]/,$F[6])' file

相关内容