更改输出 bash 中某些行的颜色

更改输出 bash 中某些行的颜色

我有驱动器诊断命令的输出。

Slot Number        : 0   
Drive's position   : DiskGroup 0  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 447.130 GB [0x37e436b0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : PHYM813201FL480BGNSSDSC2KG480G7R SCV1DL58  
Foreign State      : None   
Media Type         : Solid State Device 
Temperature        : 20C (68.00 F) 
S.M.A.R.T alert    : No   

Slot Number        : 1   
Drive's position   : DiskGroup 0  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 447.130 GB [0x37e436b0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : PHYM81320058480BGNSSDSC2KG480G7R SCV1DL58  
Foreign State      : None   
Media Type         : Solid State Device 
Temperature        : 21C (69.80 F) 
S.M.A.R.T alert    : No   

Slot Number        : 2   
Drive's position   : DiskGroup 1  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 1.090 TB [0x8bba0cb0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : SEAGATE ST1200MM0099 ST31WFK0VEBK 
Foreign State      : None   
Media Type         : Hard Disk Device 
Temperature        : 22C (71.60 F) 
S.M.A.R.T alert    : No   

Slot Number        : 3   
Drive's position   : DiskGroup 1  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 1.090 TB [0x8bba0cb0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : SEAGATE ST1200MM0099 ST31WFK0T07T 
Foreign State      : None   
Media Type         : Hard Disk Device 
Temperature        : 22C (71.60 F) 
S.M.A.R.T alert    : No   

Slot Number        : 4   
Drive's position   : DiskGroup 1  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 1.090 TB [0x8bba0cb0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : SEAGATE ST1200MM0099 ST31WFK0VAJK 
Foreign State      : None   
Media Type         : Hard Disk Device 
Temperature        : 22C (71.60 F) 
S.M.A.R.T alert    : No   

Slot Number        : 5   
Drive's position   : DiskGroup 1  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 1.090 TB [0x8bba0cb0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : SEAGATE ST1200MM0099 ST31WFK0SYPC 
Foreign State      : None   
Media Type         : Hard Disk Device 
Temperature        : 22C (71.60 F) 
S.M.A.R.T alert    : No   

Slot Number        : 6   
Drive's position   : DiskGroup 1  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 1.090 TB [0x8bba0cb0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : SEAGATE ST1200MM0099 ST31WFK0MVN2 
Foreign State      : None   
Media Type         : Hard Disk Device 
Temperature        : 22C (71.60 F) 
S.M.A.R.T alert    : No   

Slot Number        : 7   
Drive's position   : DiskGroup 1  
Media Error        : 0   
Other Error        : 0   
Predictive Failure : 0   
Raw Size           : 1.090 TB [0x8bba0cb0 Sectors]
Firmware state     : Online, Spun Up 
Inquiry Data       : SEAGATE ST1200MM0099 ST31WFK0SZ2L 
Foreign State      : None   
Media Type         : Hard Disk Device 
Temperature        : 22C (71.60 F) 
S.M.A.R.T alert    : No 

我只想对每个驱动器的第 3、4、5、7、9 和 12 行“:”符号后进行更改。这些结果是标准,但如果它有不同的内容,我想添加一些颜色。例如:

Slot Number        : 7   
Drive's position   : DiskGroup 1  
Media Error        : 4  (I want the whole line in red)
Other Error        : 3  (I want the whole line in red)
Predictive Failure : 1  (I want the whole line in red)
Raw Size           : 1.090 TB [0x8bba0cb0 Sectors]
Firmware state     : Failed. (I want the whole line in red)
Inquiry Data       : SEAGATE ST1200MM0099 ST31WFK0SZ2L 
Foreign State      : Unconfigured  (I want the whole line in red)
Media Type         : Hard Disk Device 
Temperature        : 22C (71.60 F) 
S.M.A.R.T alert    : Yes  (I want the whole line in red)

我想对每个驱动器进行这些更改,驱动器数量是可变的,有时多有时少。

我已经尝试过这个但不起作用。

awk -F ':' '$1~/^(Media Error|Other Error|Predictive Failure)$/ && $2 > 0 {print "\033[31m" $0 "\e[0m"; next} 1'

答案1

你已经非常接近做对了。我将用 Bash 和 Awk 来回应。您似乎要求的是:

$ awk '/(Media Error|Other Error|Predictive Failure|Firmware state|Foreign State|S\.M\.A\.R\.T alert)[[:blank:]]+:/{print "\033[31m" $0"\033[0m"; next} 1' < <(your_drive_diag_command)

您在发布之前所做的尝试值得一些评论:

  • -F ':'
    仅当您确实需要对记录的字段进行操作时,指定与默认空格不同的字段分隔符才有用。这里的情况似乎并非如此。

  • $1 ~ /^(Media Error|Other Error|Predictive Failure)$/ ...
    您可以使用 (OR) 布尔值测试第一个字段($1在指定字段分隔符之前:)的字符串值的 3 种不同可能性|。原则上这很好,但在这种情况下,您可能只需测试整个记录 ( $0) 中任何位置的字符串是否存在,只需确保您使用\s+:Gawk 或[[:blank:]]+:任何 Awk 风格完成所需的字符串正则表达式即可。这会在:每个查找的字符串的冒号之前添加多个空格/制表符 >= 1 。换句话说你大概可以取消$1使用涉及^和 的正则表达式进行测试$

  • 为了保持一致性,我调整了你的颜色编码,所以\e变成了\033

编辑1:
遵循 @JosueBaquerizo 的附加规范,逻辑更改为包含$1和上的条件语句$2

$ awk -F ' *: *' '
      ($1 ~ /Media Error|Other Error|Predictive Failure/ && $2 > 0 ||
       $1 ~ /Firmware state/ && $2 ~ "Failed" ||
       $1 ~ /Foreign State/ && $2 ~ "Unconfigured" || 
       $1 ~ /S\.M\.A\.R\.T alert/ && $2 ~ "Yes") {print "\033[31m" $0"\033[0m"; next} 1' < <(your_drive_diag_command)

答案2

使用任何 awk:

$ awk -F '[[:space:]]*:[[:space:]]*' '
    BEGIN {
        tag2val["Media Error"]          = 0
        tag2val["Other Error"]          = 0
        tag2val["Predictive Failure"]   = 0
        tag2val["Firmware state"]       = "Online, Spun Up"
        tag2val["Foreign State"]        = "None"
        tag2val["S.M.A.R.T alert"]      = "No"
    }
    {
        tag = $1
        val = $2
        sub(/^[[:space:]]+/,"",tag)
        sub(/[[:space:]]+$/,"",val)
    }
    (tag in tag2val) && (val != tag2val[tag]) {
        $0 = "\033[31m" $0 "\033[0m"
    }
    { print }
' file

您只需在 周围包含空格,:以便 $2 中的第一个内容不是空格,并从行尾删除任何尾随空格(例如输入中的空格)。我还整理了您的颜色结束转义序列并设置 $0 而不是在那里打印,这样您就不需要next来自两个不同位置的 和 输出。

相关内容