
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 awk
Skript druckt die eingegebene Datensatznummer minus 1, wenn die aktuelle Zeile gleich ist, Firmware state: Rebuild
und 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 übereinstimmtFirmware 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 desgrep
obigen Befehls wird dann durch diesen geleitetcut
, 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 gedrucktcommand
. Dacommand
hier dasgrep | cut
Obige ist, dessen Ausgabe die Zeilennummer (15
) ist, wird dies die Zeilennummer minus eins als speichern$var
.
Firmware state: Rebuild again
Beachten Sie, dass die obige Lösung auch mit einer Zeile wie oder allem anderen übereinstimmt , das Firmware state: Rebuild
als 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 awk
anstelle von cut
Shell-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 q
Befehl anstelle des Q
Befehls zu verwenden.
Es ist notwendig, den letzten Wert beispielsweise über den | tail -1
Befehl abzutrennen. Oder auf eine ausgefeiltere Art:
: $(sed -n '/,/!q;=' file)
echo $_
14