我在Teradata数据库上工作,并有一个空格检查脚本。脚本应该将标志提升为CRITICAL或WARNING,具体取决于脚本开头定义的空间使用值。
我的示例SQL文件输出是(DatabaseOutput.log)文件如下,该文件用作awk块的输入。
### Some multiline Database query, resulting in Database Space usage
*** Query completed. 11 rows found. 4 columns returned.
*** Total elapsed time was 11 seconds.
## Output of the query, I am interested in DatabaseName, Perc2, MaxPerm
DatabaseName Perc Perc2 MaxPerm
---------------------------------------------------- ---------------------- ------- -----------
AAA 9.21899768137583E-001 92.19 10102320
BBB 9.19923819717036E-001 91.99 524160
CCC 9.17517791271651E-001 91.75 1687440
DDD 9.15820363471060E-001 91.58 816720
EEE 9.09293748338489E-001 90.93 149760
FFF 9.07840905921109E-001 90.78 6934080
GGG 9.04946085680591E-001 90.49 7273440
HHH 8.54498111733230E-001 85.45 2538960
III 8.22783559253080E-001 82.28 7598400
JJJ 8.02181524253446E-001 80.22 8077680
+---------+---------+---------+---------+---------+---------+---+---------+-
所需的输出是
WARNING AAA 92.19 10102320
WARNING BBB 91.99 524160
WARNING CCC 91.75 1687440
WARNING DDD 91.58 816720
WARNING EEE 90.93 149760
WARNING FFF 90.78 6934080
WARNING GGG 90.49 7273440
我有工作awk代码,需要三次传递..它可以减少到一个awk传递?
工作awk代码:
cLvlCRIT=95
cLvlWARN=90
cat DatabaseOutput.log |
awk '/-------------------/,/^$/' | # captures output block; it excludes query, logon, logoff information and header line but keeps separator's line.
awk '{if (NR >= 2) {print}}' | # removes separator line, prints all lines from line 2 to EOF
awk -v lLvlCRIT=$cLvlCRIT -v lLvlWARN=$cLvlWARN ' {
if ( $1 != "StartCapture" && $3 >= lLvlCRIT ) {
printf("%11s%30s%10s%10s\n", "CRITICAL",$1,$3,$4)
}
if ( $1 != "StartCapture" && $3 >= lLvlWARN && $3 < lLvlCRIT ) {
printf("%11s%30s%10s%10s\n", "WARNING",$1,$3,$4)
}
} '
提前致谢 !
你的awk
看起来像这样:
awk -v lLvlCRIT="$cLvlCRIT" -v lLvlWARN="$cLvlWARN" '
/^---/,/^$/ {
if ( $0 ~ "^---" || $0 ~ "^$" ) next
if ( $3 >= lLvlCRIT )
printf("%11s%30s%10s%10s\n", "CRITICAL",$1,$3,$4)
else if ( $3 >= lLvlWARN )
printf("%11s%30s%10s%10s\n", "WARNING",$1,$3,$4)
}' DatabaseOutput.lo
在awk
中指定模式范围可能很棘手,并且标志是首选方法。有关更多信息,请参阅Specifying Record Ranges with Patterns。
您可以使用标志来获取awk中的块:
awk -v lLvlCRIT="$cLvlCRIT" -v lLvlWARN="$cLvlWARN" '
/^----------------------------------------------------/ {block=1; next}
/^$/ && block {exit} # if there is only one data block pattern - exit
# otherwise just reset block to 0 to find next block
block { your code on the block }'
所以重现你的例子:
awk -v lLvlCRIT="$cLvlCRIT" -v lLvlWARN="$cLvlWARN" '
/^----------------------------------------------------/ {block=1; next}
/^$/ && block {exit}
block {if ( $3 >= lLvlCRIT )
printf("%11s%30s%10s%10s\n", "CRITICAL",$1,$3,$4)
else if ( $3 >= lLvlWARN )
printf("%11s%30s%10s%10s\n", "WARNING",$1,$3,$4) }' file
WARNING AAA 92.19 10102320
WARNING BBB 91.99 524160
WARNING CCC 91.75 1687440
WARNING DDD 91.58 816720
WARNING EEE 90.93 149760
WARNING FFF 90.78 6934080
WARNING GGG 90.49 7273440
谷歌UUOC并且永远不会使用范围表达式,因为它们使得琐碎的任务变得非常简单,但是需要完全重写或复制条件,甚至更有趣:
awk -v lLvlCRIT="$cLvlCRIT" -v lLvlWARN="$cLvlWARN" '
inBlock {
if ( $3 >= lLvlCRIT ) { level = "CRITICAL" }
else if ( $3 >= lLvlWARN ) { level = "WARNING" }
else if (NF) { next }
else { exit }
printf "%11s%30s%10s%10s\n", level, $1, $3, $4
}
/-------------------/ { inBlock=1 }
' DatabaseOutput.log
以下awk
也可以帮助你。
awk -v cLvlCRIT="$cLvlCRIT" -v cLvlWARN="$cLvlWARN" -v space=" " '
/^$/||/^+/{
flag="";
next
}
/^----------/{
flag=1;
next
}
flag && $3>=cLvlWARN{
val=$1 OFS $3 OFS $4;
printf("%s"space"%s\n",$3>=cLvlCRIT?"CRITICAL":($3>=cLvlWARN && $3<cLvlCRIT?"WARNING":""),val)
}
' Input_file
这将根据您的示例输入进行。
#!/bin/bash
cLvlCRIT=95
cLvlWARN=90
grep -E '^[a-zA-Z]+[ ]+[0-9.]+' DatabaseOutput.log |
awk -v lLvlCRIT=$cLvlCRIT -v lLvlWARN=$cLvlWARN ' {
if ( $1 != "StartCapture" && $3 >= lLvlCRIT ) {
printf("%11s%30s%10s%10s\n", "CRITICAL",$1,$3,$4)
}
if ( $1 != "StartCapture" && $3 >= lLvlWARN && $3 < lLvlCRIT ) {
printf("%11s%30s%10s%10s\n", "WARNING",$1,$3,$4)
}
} '
问候!
这里主要关注的是awk
的有效输入。下面使用标志的解决方案是一种方法。这也考虑了输入的特定模式。
crit=95
warn=90
awk -v crit=$crit -v warn=$warn '
/^DatabaseName/{flag=1;next}
{$2=""}!flag{next}
$3>crit{printf "Critical\t\t%s%s",$0,ORS;next}
$3>warn{printf "Warning \t\t%s%s",$0,ORS}' DatabaseOutput.lo
Warning AAA 92.19 10102320
Warning BBB 91.99 524160
Warning CCC 91.75 1687440
Warning DDD 91.58 816720
Warning EEE 90.93 149760
Warning FFF 90.78 6934080
Warning GGG 90.49 7273440
旁注:非常肯定,awk
方法对于TB级文件来说会很慢。