bash スクリプトの行数をカウントする

bash スクリプトの行数をカウントする

Linux マシンで、行数をカウントして停止しFirmware state: Rebuild、その行番号 (行番号 0 が最初の行なので、たとえば 15 -1 = 14) を取得して変数に保存する bash スクリプトを作成しようとしています。これを行う方法がわからないため、助けを求めています。

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

アップデート

これは、ハード ドライブがスロット 0 から接続されていない場合は正しく動作しないという問題が見つかるまでは、非常にうまく機能していました。

[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

だから、答えからスロット番号4を取得する必要があります。つまり、ファームウェアの状態を取得する必要があります。再構築は1行目、次に-1で0行目を取得し、スロット番号4を取得します。

つまりvarは4になる

どうすればいいでしょうか?

ティア

答え1

awk

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

スクリプトawkは、現在の行が と等しい場合に入力レコード番号から 1 を引いた値を出力してFirmware state: Rebuildスクリプトを終了します。コマンド置換の出力は$(...)、変数 に割り当てられますvar

答え2

これで望みどおりの結果が得られそうです:

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

説明

  • grep -m1 -n 'Firmware state: Rebuild': これは、 に一致する最初の ( -m 1) 行を検索しFirmware state: Rebuild、その行を行番号 ( -n) を含めて出力します。

    $ grep -m1 -n 'Firmware state: Rebuild' file 
    15:Firmware state: Rebuild
    
  • cut -d: -f1: 上記の出力はgrep、これをパイプして、フィールド区切り文字としてcut受け取り:、最初のフィールドである行番号を出力します。 * var=$(( $(command) -1 )): この$(( ))構造により、数学演算を実行できます。例:

    $ echo $((10-2))
    8
    

    この$(command)構造により、出力コマンドの出力を変数のように扱います。したがって、は$(( $(command) -1 ))の出力から 1 を減算した結果を出力します。ここには上記があり、その出力は行番号 ( ) であるcommandため、これにより行番号から 1 を引いた値が として保存されます。commandgrep | cut15$var


上記の解決策は、 のような行Firmware state: Rebuild againや、 を部分文字列として含むその他の行にも一致することに注意してくださいFirmware state: Rebuild。行全体に 以外の何も含まれていない場合にのみ一致するようにする必要がある場合はFirmware state: Rebuild、代わりにこれを使用します。

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

答え3

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

これは terdon の回答のバリエーションであり、awkの代わりにcutとシェル演算を使用して、ゼロベースの行番号を計算します。

答え4

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

またはアンチパターンを使用します:

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

指定されたパターンで行番号を出力します。この場合、追加の数学的アクションが必要です。

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

またはアンチパターンを使用します:

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

パターンに一致する前の行番号を出力します。ここでは、コマンドqの代わりに コマンドを使用できますQ
たとえば、| tail -1コマンドを使用して最後の値を区切る必要があります。または、より洗練された方法:

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

関連情報