Bash-Skript zählt Zeilen

Bash-Skript zählt Zeilen

Ich versuche, auf einem Linux-Rechner ein Bash-Skript zu schreiben, das Zeilen zählt und bei stoppt Firmware state: Rebuild, dann diese Zeilennummer abruft (z. B. 15 -1 = 14, da Zeilennummer 0 die erste Zeile ist) und in einer Variablen speichert. Ich weiß nicht, wie das geht, also brauche ich Hilfe.

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

Aktualisieren

Das hat wirklich gut funktioniert, bis wir ein Problem festgestellt haben: Wenn die Festplatten nicht an Steckplatz 0 angeschlossen sind, funktioniert es nicht richtig.

[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

Was ich also brauche, ist, aus der Antwort die Steckplatznummer 4 zu erhalten. Ich müsste also den Firmware-Status „Rebuild“ abrufen, also Zeile 1, dann -1, um Zeile 0 zu erhalten, und dann die Steckplatznummer 4.

Die Var-Endwerte sind also 4

Wie würde ich das machen?

TIA

Antwort1

Mit awk:

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

Das awkSkript druckt die eingegebene Datensatznummer minus 1, wenn die aktuelle Zeile gleich ist, Firmware state: Rebuildund beendet das Skript. Die Ausgabe der Befehlsersetzung $(...)wird dann der Variablen zugewiesen var.

Antwort2

Dies sollte bewirken, was Sie möchten:

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

Erläuterung

  • grep -m1 -n 'Firmware state: Rebuild'-m 1: dadurch wird nach der ersten ( ) Zeile gesucht , die mit übereinstimmt Firmware state: Rebuild, und diese Zeile einschließlich ihrer Zeilennummer ( -n) gedruckt:

    $ grep -m1 -n 'Firmware state: Rebuild' file 
    15:Firmware state: Rebuild
    
  • cut -d: -f1: Die Ausgabe des grepobigen Befehls wird dann durch diesen geleitet cut, der :als Feldtrennzeichen das erste Feld, die Zeilennummer, verwendet und ausgibt. * var=$(( $(command) -1 )): Mit dieser $(( ))Konstruktion können wir mathematische Operationen durchführen. Zum Beispiel:

    $ echo $((10-2))
    8
    

    Das $(command)Konstrukt ermöglicht uns dieAusgabeeines Befehls, als wäre es eine Variable. Daher $(( $(command) -1 ))wird das Ergebnis der Subtraktion von 1 von der Ausgabe von gedruckt command. Da commandhier das grep | cutObige ist, dessen Ausgabe die Zeilennummer ( 15) ist, wird dies die Zeilennummer minus eins als speichern $var.


Firmware state: Rebuild againBeachten Sie, dass die obige Lösung auch mit einer Zeile wie oder allem anderen übereinstimmt , das Firmware state: Rebuildals Teilzeichenfolge enthält. Wenn Sie sicherstellen möchten, dass sie nur übereinstimmt, wenn die gesamte Zeile nichts anderes als enthält Firmware state: Rebuild, verwenden Sie stattdessen Folgendes:

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

Antwort3

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

Dies ist eine Variante der Antwort von Terdon, bei der awkanstelle von cutShell-Arithmetik verwendet wird, um die nullbasierte Zeilennummer zu berechnen.

Antwort4

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

Oder mit Antimuster:

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

Druckt die Zeilennummer mit dem angegebenen Muster. In diesem Fall sind zusätzliche mathematische Aktionen erforderlich.

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

Oder mit Antimuster:

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

Druckt Zeilennummern vor dem Mustervergleich. Hier ist es möglich, den qBefehl anstelle des QBefehls zu verwenden.
Es ist notwendig, den letzten Wert beispielsweise über den | tail -1Befehl abzutrennen. Oder auf eine ausgefeiltere Art:

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

verwandte Informationen