【问题标题】:reading multiple matches into arrays with bash使用 bash 将多个匹配项读入数组
【发布时间】:2021-12-29 18:40:15
【问题描述】:

实用程序“sas2ircu”可以为连接到主机的每个硬盘驱动器输出多行。单个驱动器的输出示例如下所示:

  Enclosure #                             : 5
  Slot #                                  : 20
  SAS Address                             : 5003048-0-185f-b21c
  State                                   : Ready (RDY)

我有一个 bash 脚本,它执行 sas2ircu 命令并对输出执行以下操作:

  1. 通过 RDY 字符串识别驱动器
  2. 将外壳的数值(即5)读入数组'enc'
  3. 将槽的数值(即20)读入另一个数组'槽'

我的代码达到了它的目的,但我想弄清楚是否可以将它组合成一行并运行 sas2ircu 命令一次而不是两次。

mapfile -t enc < <(/root/sas2ircu 0 display|grep -B3 RDY|awk '/Enclosure/{print $NF}')
mapfile -t slot < <(/root/sas2ircu 0 display|grep -B2 RDY|awk '/Slot/{print $NF}')

我已经阅读了大量关于 awk 的内容,但我对它还是很陌生,还没有想出比我所拥有的更好的东西。有什么建议吗?

【问题讨论】:

    标签: arrays bash awk


    【解决方案1】:

    应该能够消除grep并将awk脚本合并成一个awk脚本;一般的想法是捕获机箱和插槽数据,然后如果/当我们看到State/RDY 我们将机箱和插槽打印到标准输出:

    awk '/Enclosure/{enclosure=$NF}/Slot/{slot=$NF}/State.*(RDY)/{print enclosure,slot}' 
    

    我没有sas2ircu,所以我将模拟一些数据(基于 OP 的示例):

    $ cat raw.dat
      Enclosure #                             : 5
      Slot #                                  : 20
      SAS Address                             : 5003048-0-185f-b21c
      State                                   : Ready (RDY)
    
      Enclosure #                             : 7
      Slot #                                  : 12
      SAS Address                             : 5003048-0-185f-b21c
      State                                   : Ready (RDY)
    
      Enclosure #                             : 9
      Slot #                                  : 23
      SAS Address                             : 5003048-0-185f-b21c
      State                                   : Off (OFF)
    

    模拟thw sas2ircu调用:

    $ cat raw.dat | awk '/Enclosure/{enclosure=$NF}/Slot/{slot=$NF}/State.*(RDY)/{print enclosure,slot}'
    5 20
    7 12
    

    更难的部分是将这些读入 2 个单独的数组,我不知道使用单个命令执行此操作的简单方法(例如,mapfile 不提供拆分输入文件的方法跨 2 个数组)。

    使用bash/while 循环的一个想法:

    unset enc slot
    
    while read -r e s
    do
        enc+=( ${e} )
        slot+=( ${s} )
    done < <(cat raw.dat | awk '/Enclosure/{enclosure=$NF}/Slot/{slot=$NF}/State.*(RDY)/{print enclosure,slot}')
    

    这会生成:

    $ typeset -p enc slot
    declare -a enc=([0]="5" [1]="7")
    declare -a slot=([0]="20" [1]="12")
    

    【讨论】:

      猜你喜欢
      • 2021-04-21
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      相关资源
      最近更新 更多