script bash contando linhas

script bash contando linhas

Estou tentando escrever um script bash em uma máquina Linux para contar linhas e parar em Firmware state: Rebuild, obter esse número de linha (por exemplo, 15 -1 = 14, já que o número de linha 0 é a primeira linha) e salvá-lo em uma variável. Não sei como fazer isso, então procuro ajuda.

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

Atualizar

Isso tem funcionado muito bem até encontrarmos um problema: se os discos rígidos não estiverem conectados no slot 0, ele não funciona corretamente.

[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

Então, o que preciso é obter o slot número 4 da resposta. Portanto, seria necessário obter o estado do firmware: Reconstruir, que é a linha 1 e depois -1 para obter a linha 0 e, em seguida, obter o slot número 4

Então o var acaba sendo 4

Como eu faria isso?

TIA

Responder1

Com awk:

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

O awkscript imprime o número do registro de entrada menos 1 quando a linha atual é igual Firmware state: Rebuilde sai do script. A saída da substituição do comando $(...)é então atribuída à variável var.

Responder2

Isso deve fazer o que você deseja:

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

Explicação

  • grep -m1 -n 'Firmware state: Rebuild': isso irá procurar pela primeira ( -m 1) linha correspondente Firmware state: Rebuilde imprimir essa linha incluindo seu número de linha ( -n):

    $ grep -m1 -n 'Firmware state: Rebuild' file 
    15:Firmware state: Rebuild
    
  • cut -d: -f1: a saída acima grepé então canalizada através deste cutque toma :como delimitador de campo e imprime o primeiro campo, o número da linha. * var=$(( $(command) -1 )): A $(( ))construção nos permite realizar operações matemáticas. Por exemplo:

    $ echo $((10-2))
    8
    

    A $(command)construção nos permite usar osaídade um comando como se fosse uma variável. Então, $(( $(command) -1 ))imprimirá o resultado da subtração de 1 da saída de command. Como commandaqui está o grep | cutacima, cuja saída é o número da linha ( 15), isso salvará o número da linha menos um como $var.


Observe que a solução acima também corresponderá a uma linha como Firmware state: Rebuild againou qualquer outra coisa que contenha Firmware state: Rebuilduma substring. Se você precisar garantir que ele corresponda apenas quando a linha inteira não contiver nada além de Firmware state: Rebuild, use isto:

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

Responder3

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

Esta é uma variação da resposta de Terdon, usando awkem vez de cute aritmética shell para calcular o número da linha com base em zero.

Responder4

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

Ou usando antipadrão:

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

Imprime o número da linha com o padrão fornecido. Neste caso, são necessárias ações matemáticas adicionais.

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

Ou usando antipadrão:

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

Imprime números de linha antes de corresponder ao padrão. Aqui é possível usar o qcomando em vez do Qcomando.
É necessário separar o último valor por exemplo através do | tail -1comando. Ou de uma forma mais sofisticada:

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

informação relacionada