
Я пытаюсь написать скрипт bash на машине Linux, чтобы подсчитать строки и остановиться на 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.
Как бы я это сделал?
ТИА
решение1
С awk
:
$ var=$(awk '$0=="Firmware state: Rebuild"{print --NR; exit}' file)
$ echo "$var"
14
Скрипт awk
печатает номер входной записи минус 1, когда текущая строка равна Firmware state: Rebuild
и выходит из скрипта. Затем вывод подстановки команды $(...)
присваивается переменной 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}')
Это вариация ответа Тердона, использующая awk
вместо cut
и арифметику оболочки для вычисления номера строки, отсчитываемого от нуля.
решение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