bash 脚本计算行数

bash 脚本计算行数

我正在尝试在 Linux 机器上编写一个 bash 脚本来计算行数并在 处停止Firmware state: Rebuild,然后获取该行号(例如 15 -1 = 14,因为行号 0 是第一行)并将其保存在变量中。我不知道该怎么做,所以寻求帮助。

Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Rebuild
Firmware state: Online, Spun Up

更新

这一直工作得很好,直到我们发现一个问题,如果硬盘驱动器没有从插槽 0 连接,它就无法正常工作。

[root@la43 ~]# /opt/MegaRAID/MegaCli/MegaCli64 -PDList -aALL | grep -e "Firmware state" -e "Slot"
Slot Number: 4
Firmware state: Rebuild
Slot Number: 5
Firmware state: Online, Spun Up
Slot Number: 6
Firmware state: Online, Spun Up
Slot Number: 7
Firmware state: Online, Spun Up
Slot Number: 8
Firmware state: Online, Spun Up
Slot Number: 9
Firmware state: Online, Spun Up
Slot Number: 10
Firmware state: Online, Spun Up
Slot Number: 11
Firmware state: Online, Spun Up
Slot Number: 12
Firmware state: Online, Spun Up
Slot Number: 13
Firmware state: Online, Spun Up
Slot Number: 14
Firmware state: Online, Spun Up
Slot Number: 15
Firmware state: Online, Spun Up

所以我需要的是从答案中获取插槽号 4。因此需要获取固件状态:重建第 1 行,然后 -1 获取第 0 行,然后获取插槽号 4

所以var最终是4

我该怎么做?

TIA

答案1

awk

$ var=$(awk '$0=="Firmware state: Rebuild"{print --NR; exit}' file)
$ echo "$var"
14

awk当当前行等于Firmware state: Rebuild并退出脚本时,脚本打印输入记录号减 1。然后将命令替换的输出$(...)分配给变量var

答案2

这应该做你想要的:

$ var=$(( $(grep -m1 -n 'Firmware state: Rebuild' file | cut -d: -f1) -1 ))
$ echo $var
14      

解释

  • grep -m1 -n 'Firmware state: Rebuild':这将搜索第一个 ( -m 1) 行匹配Firmware state: Rebuild,并打印该行,包括其行号 ( -n):

    $ grep -m1 -n 'Firmware state: Rebuild' file 
    15:Firmware state: Rebuild
    
  • cut -d: -f1:上面的输出grep然后通过管道传输cut,它:作为字段分隔符并打印第一个字段,即行号。 * var=$(( $(command) -1 )):该$(( ))构造允许我们执行数学运算。例如:

    $ echo $((10-2))
    8
    

    $(command)构造让我们可以使用输出一个命令就好像它是一个变量一样。因此,$(( $(command) -1 ))将打印从 的输出中减去 1 的结果command。由于command上面grep | cut的输出是行号 ( 15),因此会将行号减一保存为$var


请注意,上面的解决方案还将匹配类似或包含子字符串Firmware state: Rebuild again的任何其他内容的行。Firmware state: Rebuild如果您需要确保它仅在整行仅包含 时才匹配Firmware state: Rebuild,请改用:

var=$(( $(grep -xm1 -n 'Firmware state: Rebuild' file | cut -d: -f1) -1 ))

答案3

var=$(grep -n "Firmware state: Rebuild" filename| awk -F ":" '{print $1-1}')

这是 terdon 答案的一个变体,使用awk替代cut和 shell 算术来计算从零开始的行号。

答案4

sed -n '/Rebuild$/!d;=' file

或者使用反模式:

sed -n '/,/d;=' file
15

使用给定模式打印行号。在这种情况下,需要额外的数学操作。

sed -n '/Rebuild$/Q;=' file

或者使用反模式:

sed -n '/,/!Q;=' file
1
2
3
4
5
6
7
8
9
10
11
12
13
14

在匹配模式之前打印行号。这里可以用q命令代替命令Q
有必要通过命令分隔最后一个值| tail -1。或者以更复杂的方式:

: $(sed -n '/,/!q;=' file)
echo $_
14

相关内容