
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 awk
script imprime o número do registro de entrada menos 1 quando a linha atual é igual Firmware state: Rebuild
e 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 correspondenteFirmware state: Rebuild
e 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 acimagrep
é então canalizada através destecut
que 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 decommand
. Comocommand
aqui está ogrep | cut
acima, 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 again
ou qualquer outra coisa que contenha Firmware state: Rebuild
uma 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 awk
em vez de cut
e 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 q
comando em vez do Q
comando.
É necessário separar o último valor por exemplo através do | tail -1
comando. Ou de uma forma mais sofisticada:
: $(sed -n '/,/!q;=' file)
echo $_
14