
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 awk
script imprime el número de registro de entrada menos 1 cuando la línea actual es igual Firmware state: Rebuild
y 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 coincidaFirmware state: Rebuild
e 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 logrep
anterior luego se canaliza a través de estocut
, 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 decommand
. Dado quecommand
aquí está logrep | cut
anterior, 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 again
o cualquier otra cosa que contenga Firmware state: Rebuild
una 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 awk
en lugar de cut
y 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 q
comando en lugar del Q
comando.
Es necesario separar el último valor, por ejemplo mediante el | tail -1
comando. O de una forma más sofisticada:
: $(sed -n '/,/!q;=' file)
echo $_
14