我正在尝试在 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