如何在使用 awk 完成模式匹配后打印新行

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

有如下数据。路径将处于活动就绪 运行 状态。如果没有,可以忽略那些。

[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

正在尝试以以下格式打印。得到如下输出。

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

但希望在打印整个输出后获得新的 line/shell 提示。尝试使用“\n” multipath -ll | awk '/PURE/ {print $1 " " $2} /active ready 运行/ {printf $(NF-4) "\n"}' 但它没有打印正如预期的那样。请帮我得到如下。

预期输出-:

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

在每个 Unix 机器上的任何 shell 中使用任何 awk:

$ cat tst.awk
/PURE/ {
    if ( NR>1 ) {
        prt()
    }
    cnt = 0
}
{ buf[++cnt] = [=10=] }
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

OP 的当前 awk 代码已关闭;只需要添加几个条件检查来确定何时终止一行 printf 调用;对 OP 的当前 awk 代码进行一些更改:

awk '
/PURE/                 { if (NR>1) print ""                  # terminate previous line?
                         print ,
                         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?
'

这会生成:

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

我会按照以下方式改进您的代码

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

在管道命令输出后

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

进去,会产生

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

说明:我所做的唯一更改是使用 {print (j++?"\n":"") " " } 替换 {print " " },因此它会使用换行符在除第一个打印内容之外的所有内容之前添加。根据您的要求,输出的第 2 行和第 4 行会有尾随空格。为了获得所需的输出,我将 so-called 三元运算符 condition?valueiftrue:valueiffalse 与变量后的 ++ 组合在一起。 j++ 第一次执行时值为 0(然后使用空字符串),后续执行时值为 1,2,3...(然后使用换行符)。 免责声明:此解决方案旨在通过对原始代码进行最少的改动来获得所需的输出。

(在 gawk 4.2.1 中测试)