Awk print matched column if exists else print not

2019-02-28 07:21发布

My text file looks like below

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

I am using the below awk code to print the matched string and extract whatever is after the "=".

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

For example I would search for "inbound=" and extract the "100". But the tricky part is "inbound" won't there in all the lines of the text Now I would like to print "0" if a line doesn't have the word "inbound".

Expected output

100
100
0 Not Found

标签: bash shell awk
3条回答
Summer. ? 凉城
2楼-- · 2019-02-28 07:25

Whenever you have name=value pairs in your input it's best to first create an array of those mappings (f[] below) and then you can just print (or do anything else with) the values by name:

$ 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

Want to do the same for "outbound" or any other field? Just init the name variable n accordingly"

$ 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
查看更多
我命由我不由天
3楼-- · 2019-02-28 07:37

Input

$ 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

Output

$ 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

Explanation

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
查看更多
Rolldiameter
4楼-- · 2019-02-28 07:45

Using GNU awk

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

In perl

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

In sed

sed 's/.*inbound=\([0-9]\+\).*/\1/;t;s/.*/0/' file
查看更多
登录 后发表回答