veeranjaneya reddy
veeranjaneya reddy

Reputation: 25

How to print the new line after completing the pattern match using awk

Have the data like below. Paths will be with active ready running state. If not, can ignore those.

[root@dev-vm:~]# multipath -ll
dev_mig (3624a9370402ea6a5e67a4646002114g7) dm-11 PURE,FlashArray
size=5.0T features='0' hwhandler='0' wp=rw
`-+- policy='queue-length 0' prio=1 status=active
  |- 0:0:3:2 sder 129:48 active ready running
  |- 0:0:2:2 sdep 129:16 active ready running
  |- 1:0:2:2 sdkh 66:336 active ready running
  `- 1:0:3:2 sdkj 66:368 active ready running
dev_mig_temp (3624a9370402ea6a5e67a4646002114g6) dm-10 PURE,FlashArray
size=6.0T features='0' hwhandler='0' wp=rw
`-+- policy='queue-length 0' prio=1 status=active
  |- 0:0:2:1 sdeo 129:0  active ready running
  |- 0:0:3:1 sdeq 129:32 active ready running
  |- 1:0:2:1 sdkg 66:320 active ready running
  `- 1:0:3:1 sdki 66:352 active ready running

Trying to print in the below format. Getting the output as below.

[root@dev-vm:~]# multipath -ll | awk '/PURE/ {print $1 " " $2} /active ready running/ {printf $(NF-4) " "}'
dev_mig (3624a9370402ea6a5e67a4646002114g7)
sder sdep sdkh sdkj dev_mig_temp (3624a9370402ea6a5e67a4646002114g6)
sdeo sdeq sdkg sdki [root@dev-vm:~]#

But looking to get a new line/shell prompt after printing the entire output. Tried using "\n" multipath -ll | awk '/PURE/ {print $1 " " $2} /active ready running/ {printf $(NF-4) "\n"}' but it is not printing as epxected. Please help me to get as below.

Expected output -:

    [root@dev-vm:~]# multipath -ll | awk '/PURE/ {print $1 " " $2} /active ready running/ {printf $(NF-4) " "}'
    dev_mig (3624a9370402ea6a5e67a4646002114g7)
    sder sdep sdkh sdkj 
    dev_mig_temp (3624a9370402ea6a5e67a4646002114g6)
    sdeo sdeq sdkg sdki 
[root@dev-vm:~]#

Upvotes: 0

Views: 275

Answers (3)

Daweo
Daweo

Reputation: 36450

I would ameloriate your code following way

awk '/PURE/ {print (j++?"\n":"") $1 " " $2} /active ready running/ {printf $(NF-4) " "}'

after piping command which output

dev_mig (3624a9370402ea6a5e67a4646002114g7) dm-11 PURE,FlashArray
size=5.0T features='0' hwhandler='0' wp=rw
`-+- policy='queue-length 0' prio=1 status=active
  |- 0:0:3:2 sder 129:48 active ready running
  |- 0:0:2:2 sdep 129:16 active ready running
  |- 1:0:2:2 sdkh 66:336 active ready running
  `- 1:0:3:2 sdkj 66:368 active ready running
dev_mig_temp (3624a9370402ea6a5e67a4646002114g6) dm-10 PURE,FlashArray
size=6.0T features='0' hwhandler='0' wp=rw
`-+- policy='queue-length 0' prio=1 status=active
  |- 0:0:2:1 sdeo 129:0  active ready running
  |- 0:0:3:1 sdeq 129:32 active ready running
  |- 1:0:2:1 sdkg 66:320 active ready running
  `- 1:0:3:1 sdki 66:352 active ready running

into it, it will produce

dev_mig (3624a9370402ea6a5e67a4646002114g7)
sder sdep sdkh sdkj 
dev_mig_temp (3624a9370402ea6a5e67a4646002114g6)
sdeo sdeq sdkg sdki 

Explanation: only change I did make was replacing {print $1 " " $2} using {print (j++?"\n":"") $1 " " $2} so it will prepend all but first these print using newline. According to your requirement there will be trailing spaces in 2nd and 4th line of output. To get desired output I combined so-called ternary operator condition?valueiftrue:valueiffalse with ++ after variable. j++ value is 0 for 1st execution (then empty string is used) and 1,2,3... for following executions (then newline is used). Disclaimer: this solution aims to get desired output with minimal alteration of original code.

(tested in gawk 4.2.1)

Upvotes: 0

markp-fuso
markp-fuso

Reputation: 34444

OP's current awk code is close; just need to add a couple conditional checks to determine when to terminate a line of printf calls; making a few changes to OP's current awk code:

awk '
/PURE/                 { if (NR>1) print ""                  # terminate previous line?
                         print $1,$2
                         pfx=""                              # reset prefix to empty string
                       }
/active ready running/ { printf "%s%s", pfx, $(NF-4)         # 1st match prints with a prefix of empty string
                         pfx=OFS                             # set prefix to OFS for rest of matches
                       }
END                    { if (pfx==OFS) print "" }            # terminate last line?
'

This generates:

dev_mig (3624a9370402ea6a5e67a4646002114g7)
sder sdep sdkh sdkj
dev_mig_temp (3624a9370402ea6a5e67a4646002114g6)
sdeo sdeq sdkg sdki

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 203532

Using any awk in any shell on every Unix box:

$ cat tst.awk
/PURE/ {
    if ( NR>1 ) {
        prt()
    }
    cnt = 0
}
{ buf[++cnt] = $0 }
END { prt() }

function prt(   a,i,rest) {
    split(buf[1],a)
    print a[1], a[2]
    for ( i=4; i<=cnt; i++ ) {
        if ( buf[i] ~ /active ready running/ ) {
            split(buf[i],a)
            rest = (rest == "" ? "" : rest OFS) a[3]
        }
    }
    if ( rest != "" ) {
        print rest
    }
}

$ awk -f tst.awk file
dev_mig (3624a9370402ea6a5e67a4646002114g7)
sder sdep sdkh sdkj
dev_mig_temp (3624a9370402ea6a5e67a4646002114g6)
sdeo sdeq sdkg sdki

Upvotes: 1

Related Questions