AWK Command Output

69 Views Asked by At

I'm trying to capture the value of "License Name", "User", "Total Number of Licenses", "Number of licenses used", "Expiry Date", "License Checkout Date", "Server name" on the below output:

Users of avy_amba_portfolio:  (Total of 21 licenses issued;  Total of 5 licenses in use)
  "avy_amba_portfolio" v1.5, vendor: AVERYDES, expiry: 30-apr-2024

    user1 server1 /dev/pts/5 (v0.20220708) (license_server_1/1234 3402), start Tue 3/5 22:22
    user1 server6 /dev/pts/22 (v0.20220708) (license_server_1/1234 488), start Wed 3/6 1:19
    user1 server1 /dev/pts/80 (v0.20220708) (license_server_1/1234 3554), start Wed 3/6 23:55
    user1 server1 /dev/pts/83 (v0.20220708) (license_server_1/1234 5850), start Thu 3/7 0:03
    user2 server1 /dev/pts/47 (v0.20220920) (license_server_1/1234 1713), start Thu 3/7 3:10

Users of avy_jtag:  (Total of 6 licenses issued;  Total of 1 license in use)
  "avy_jtag" v1.5, vendor: AVERYDES, expiry: 30-apr-2024

    user1 server6 /dev/pts/22 (v0.20220708) (license_server_1/1234 1491), start Wed 3/6 1:19

I'm using the command below:

awk 'BEGIN { printf "%-20s%-20s%-30s%-25s%-20s%-30s%-20s\n", 
  "License Name", "User", "Total Number of Licenses", "Number of license used", "Expiry Date", "License Checkout Date", "Servername" }
   /Users of/ { license = $3; totallicense = $6; usedlicense = $11; 
     getline; getline; 
     next
   }
   /expiry/ { 
     expiry_date = $6; getline; getline; next
   } 
   { printf "%-20s%-20s%-30s%-25s%-20s%-30s%-20s\n", 
     license, $1, totallicense, usedlicense, expiry_date, $8" "$9" "$10, $2 
 }' /root/avery_lic_usage.log

However, it can't capture the "expiry" date on the line "avy_amba_portfolio" v1.5, vendor: AVERYDES, expiry: 30-apr-2024". Here's the sample output of the command:

License Name        User                Total Number of Licenses      Number of license used   Expiry Date         License Checkout Date         Servername
avy_amba_portfolio: user1               21                            5                                            Tue 3/5 22:22                 server1
avy_amba_portfolio: user1               21                            5                                            Wed 3/6 1:19                  server6
avy_amba_portfolio: user1               21                            5                                            Wed 3/6 23:55                 server1
avy_amba_portfolio: user1               21                            5                                            Thu 3/7 0:03                  server1
avy_amba_portfolio: user2               21                            5                                            Thu 3/7 3:10                  server1
avy_amba_portfolio:                     21                            5
avy_jtag:           user1               6                             1                                            Wed 3/6 1:19                  server6

How can I make it work? Also, I want to remove the line on the output that has blank in user field.

2

There are 2 best solutions below

4
markp-fuso On

The 1st getline; getline; next is telling awk to skip over the next two lines of input, which in this case means the expiry lines are being ignored.

Modifying the input to provide some visual differences in the data:

$ cat avery_lic_usage.log
Users of avy_amba_portfolio:  (Total of 21 licenses issued;  Total of 5 licenses in use)
  "avy_amba_portfolio" v1.5, vendor: AVERYDES, expiry: 30-apr-2024

    user1 server1 /dev/pts/5 (v0.20220708) (license_server_1/1234 3402), start Tue 3/5 22:22
    user2 server6 /dev/pts/22 (v0.20220708) (license_server_1/1234 488), start Wed 3/6 1:19
    user3 server1 /dev/pts/80 (v0.20220708) (license_server_1/1234 3554), start Wed 3/6 23:55
    user4 server1 /dev/pts/83 (v0.20220708) (license_server_1/1234 5850), start Thu 3/7 0:03
    user5 server1 /dev/pts/47 (v0.20220920) (license_server_1/1234 1713), start Thu 3/7 3:10

Users of avy_jtag:  (Total of 6 licenses issued;  Total of 1 license in use)
  "avy_jtag" v1.5, vendor: AVERYDES, expiry: 30-may-2024

    user6 server6 /dev/pts/22 (v0.20220708) (license_server_1/1234 1491), start Wed 3/6 1:19

There's no need for the getline calls if we can rely on unique patterns for the lines of interest.

One awk idea:

awk '
BEGIN             { fmt = "%-20s%-20s%-30s%-25s%-20s%-30s%-20s\n"

                    printf fmt,
                    "License Name", "User", "Total Number of Licenses",
                    "Number of license used", "Expiry Date",
                    "License Checkout Date", "Servername"
                  }

/Users of/        { license      = $3
                    totallicense = $6
                    usedlicense  = $11
                    next
                  }

/expiry/          { expiry_date  = $6
                    next
                  }

/license_server_/ { printf fmt,
                    license, $1, totallicense,
                    usedlicense, expiry_date,
                    $8" "$9" "$10, $2
                  }

' avery_lic_usage.log

This generates:

License Name        User                Total Number of Licenses      Number of license used   Expiry Date         License Checkout Date         Servername
avy_amba_portfolio: user1               21                            5                        30-apr-2024         Tue 3/5 22:22                 server1
avy_amba_portfolio: user2               21                            5                        30-apr-2024         Wed 3/6 1:19                  server6
avy_amba_portfolio: user3               21                            5                        30-apr-2024         Wed 3/6 23:55                 server1
avy_amba_portfolio: user4               21                            5                        30-apr-2024         Thu 3/7 0:03                  server1
avy_amba_portfolio: user5               21                            5                        30-apr-2024         Thu 3/7 3:10                  server1
avy_jtag:           user6               6                             1                        30-may-2024         Wed 3/6 1:19                  server6
0
Ed Morton On

Whenever you have tag-value pairings in the input I find it best to first create an array to hold that mapping and then you can access the values stored in the array by their tags as indices.

Using any awk:

$ cat tst.awk
BEGIN {
    numTags = split("License,User,Total,Used,Expiry,Checkout,Server",tags,/,/)

    split("%-20s,%-20s,%-30s,%-25s,%-20s,%-30s,%-20s",fmts,/,/)
    split("License Name,User,Total Number of Licenses,Number of Licenses Used,Expiry Date,License Checkout Date,Server Name",hdrs,/,/)

    for ( i=1; i<=numTags; i++ ) {
        printf fmts[i], hdrs[i]
    }
    print ""
}

NF {
    if ( /^Users/ ) {
        sub(/:/,"")
        tags2vals["License"]    = $3
        tags2vals["Total"]      = $6
        tags2vals["Used"]       = $11
    }
    else if ( NF < 10 ) {
        tags2vals["Expiry"]     = $NF
    }
    else {
        tags2vals["User"]       = $1
        tags2vals["Server"]     = $2
        tags2vals["Checkout"]   = $8 " " $9 " " $10

        for ( i=1; i<=numTags; i++ ) {
            tag = tags[i]
            val = tags2vals[tag]
            printf fmts[i], val
        }
        print ""
    }
}

$ awk -f tst.awk file
License Name        User                Total Number of Licenses      Number of Licenses Used  Expiry Date         License Checkout Date         Server Name
avy_amba_portfolio  user1               21                            5                        30-apr-2024         Tue 3/5 22:22                 server1
avy_amba_portfolio  user1               21                            5                        30-apr-2024         Wed 3/6 1:19                  server6
avy_amba_portfolio  user1               21                            5                        30-apr-2024         Wed 3/6 23:55                 server1
avy_amba_portfolio  user1               21                            5                        30-apr-2024         Thu 3/7 0:03                  server1
avy_amba_portfolio  user2               21                            5                        30-apr-2024         Thu 3/7 3:10                  server1
avy_jtag            user1               6                             1                        30-apr-2024         Wed 3/6 1:19                  server6

Given that approach you can trivial tweak the script to print the fields in whatever order you like, compare values, change values, etc., i.e. do whatever you like before deciding what to print.