【问题标题】:Awk print matched column if exists else print not found如果存在,则 awk 打印匹配的列,否则打印未找到
【发布时间】:2017-06-02 11:23:56
【问题描述】:

我的文本文件如下所示

date="2017-10-10" ip=192.168.1.1:22 inbound=100 outbound=100
date="2017-10-10" ip=192.168.1.1:22 inbound=100
date="2017-10-10" ip=192.168.1.1:22  outbound=100

我正在使用下面的 awk 代码打印匹配的字符串并提取“=”之后的任何内容。

awk '{for(i=1;i<=NF;i++)if($i~/inbound=/)print $(i)}'  | cut -d : -f1 | cut -d = -f2

例如,我会搜索“inbound=”并提取“100”。 但棘手的部分是“入站”不会出现在文本的所有行中 现在,如果一行没有“入站”一词,我想打印“0”。

预期输出

100
100
0 Not Found

【问题讨论】:

  • "=" 之后的内容 - 不仅适用于 inbound

标签: bash shell awk


【解决方案1】:

使用 GNU awk

awk '{print match($0,/inbound=([0-9]+)/,a)?a[1]:0}' file

在 perl 中

perl -lne 'print /inbound=(\d+)/?$1:0' file

在 sed 中

sed 's/.*inbound=\([0-9]\+\).*/\1/;t;s/.*/0/' file

【讨论】:

  • @Inian 不幸的是,最后一个要匹配的参数是 GNU awk,否则你必须搞砸 RSTARTRLENGTH
【解决方案2】:

只要您的输入中有 name=value 对,最好先创建一个包含这些映射的数组(下面的f[]),然后您可以按名称打印(或执行其他任何操作)值:

$ awk -v n="inbound" -F'[ =]+' '{delete f; for (i=1;i<NF;i+=2) f[$i]=$(i+1); print (n in f ? f[n] : "0 Not Found")}' file
100
100
0 Not Found

想对“出站”或任何其他领域做同样的事情吗?只需相应地初始化名称变量n"

$ awk -v n="outbound" -F'[ =]+' '{delete f; for (i=1;i<NF;i+=2) f[$i]=$(i+1); print (n in f ? f[n] : "0 Not Found")}' file
100
0 Not Found
100
$
$ awk -v n="date" -F'[ =]+' '{delete f; for (i=1;i<NF;i+=2) f[$i]=$(i+1); print (n in f ? f[n] : "0 Not Found")}' file
"2017-10-10"
"2017-10-10"
"2017-10-10"
$
$ awk -v n="ip" -F'[ =]+' '{delete f; for (i=1;i<NF;i+=2) f[$i]=$(i+1); print (n in f ? f[n] : "0 Not Found")}' file
192.168.1.1:22
192.168.1.1:22
192.168.1.1:22

【讨论】:

  • 不客气。不过,对于your followup question,我认为您并没有真正理解这个答案,或者为什么它与您得到的其他答案不同,因为它也为您的后续问题提供了解决方案。
【解决方案3】:

输入

$ cat file
date="2017-10-10" ip=192.168.1.1:22 inbound=100 outbound=100
date="2017-10-10" ip=192.168.1.1:22 inbound=100
date="2017-10-10" ip=192.168.1.1:22  outbound=100

输出

$ awk '{if(match($0,/inbound=[0-9]+/)){s=substr($0,RSTART,RLENGTH); print substr(s,index(s,"=")+1);next}print 0,"Not Found"}' file
100
100
0 Not Found

说明

awk '{

    # Search for word inbound=[0-9]+ in record/line/row, if found then
    if(match($0,/inbound=[0-9]+/))
    {
        # Extract word
        s=substr($0,RSTART,RLENGTH)

        # Print value which is after "="  
        print substr(s,index(s,"=")+1)

        # Go to next line
        next
    }

      # If above condition is not true then word inbound not found in line/row/record

      print 0,"Not Found"
  }
 ' file

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多