script bash contando líneas

script bash contando líneas

Estoy intentando escribir un script bash en una máquina Linux para contar líneas y detenerme en Firmware state: Rebuild, luego obtener ese número de línea (por ejemplo, 15 -1 = 14, ya que la línea número 0 es la primera línea) y guardarlo en una variable. No sé cómo hacer esto así que busco ayuda.

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

Actualizar

Esto ha funcionado muy bien hasta que encontramos un problema: si los discos duros no están conectados desde la ranura 0, no funciona correctamente.

[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

Entonces, lo que necesito es obtener la ranura número 4 de la respuesta. Por lo tanto, sería necesario obtener el estado del firmware: reconstruir, que es la línea 1, luego -1 para obtener la línea 0 y luego obtener el número de ranura 4.

Entonces la var termina siendo 4

¿Cómo haría esto?

tia

Respuesta1

Con awk:

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

El awkscript imprime el número de registro de entrada menos 1 cuando la línea actual es igual Firmware state: Rebuildy sale del script. Luego , la salida del comando de sustitución $(...)se asigna a la variable var.

Respuesta2

Esto debería hacer lo que quieres:

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

Explicación

  • grep -m1 -n 'Firmware state: Rebuild': esto buscará la primera ( -m 1) línea que coincida Firmware state: Rebuilde imprimirá esa línea incluyendo su número de línea ( -n):

    $ grep -m1 -n 'Firmware state: Rebuild' file 
    15:Firmware state: Rebuild
    
  • cut -d: -f1: la salida de lo grepanterior luego se canaliza a través de esto cut, que toma :como delimitador de campo e imprime el primer campo, el número de línea. * var=$(( $(command) -1 )): La $(( ))construcción nos permite realizar operaciones matemáticas. Por ejemplo:

    $ echo $((10-2))
    8
    

    La $(command)construcción nos permite utilizar elproducciónde un comando como si fuera una variable. Entonces, $(( $(command) -1 ))imprimirá el resultado de restar 1 de la salida de command. Dado que commandaquí está lo grep | cutanterior, cuya salida es el número de línea ( 15), esto guardará el número de línea menos uno como $var.


Tenga en cuenta que la solución anterior también coincidirá con una línea como Firmware state: Rebuild againo cualquier otra cosa que contenga Firmware state: Rebuilduna subcadena. Si necesita asegurarse de que solo coincida cuando toda la línea no contenga nada más que Firmware state: Rebuild, utilice esto en su lugar:

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

Respuesta3

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

Esta es una variación de la respuesta de terdon, que utiliza awken lugar de cuty aritmética de shell para calcular el número de línea de base cero.

Respuesta4

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

O usando antipatrón:

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

Imprime el número de línea con el patrón dado. En este caso, se requieren acciones matemáticas adicionales.

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

O usando antipatrón:

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

Imprime los números de línea antes de que coincidan con el patrón. Aquí es posible utilizar el qcomando en lugar del Qcomando.
Es necesario separar el último valor, por ejemplo mediante el | tail -1comando. O de una forma más sofisticada:

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

información relacionada