bash 腳本計算行數

bash 腳本計算行數

我試圖在 Linux 機器上編寫一個 bash 腳本來計算行數並在 處停止Firmware state: Rebuild,然後獲取該行號(例如 15 -1 = 14,因為行號 0 是第一行)並將其保存在變數中。我不知道該怎麼做,所以尋求幫助。

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

我該怎麼做?

TIA

答案1

awk

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

awk當目前行等於Firmware state: Rebuild並退出腳本時,腳本列印輸入記錄號減 1。然後將命令替換的輸出$(...)分配給變數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。由於command上面grep | cut的輸出是行號 ( 15),因此將行號減一儲存為$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和 shell 算術來計算從零開始的行號。

答案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

相關內容