如何在使用 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 中测试)
有如下数据。路径将处于活动就绪 运行 状态。如果没有,可以忽略那些。
[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 中测试)