bash-скрипт подсчета строк

bash-скрипт подсчета строк

Я пытаюсь написать скрипт 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

Связанный контент