Bla*_*ler 3 bash logs awk shell-script
我尝试过用其他方法创建 awk 脚本或脚本。
我希望日志文件中包含日期和时间变量(但包含给定单词)的给定行用特定颜色加下划线。
我在 awk 中创建了类似的东西,但它只强调某个短语,没有日期和时间,是否可以另外强调日期和时间或包含该单词的整行?
awk $'{ gsub(" DEBUG StateMachine\|entr \'NTP:nextGetTimeTimeoutState'", "\033[1;41m&\033[0m");
print }' LOG.log
Run Code Online (Sandbox Code Playgroud)
LOG.log 中的这一行看起来像这样:
2021-08-17 10:16:35,445 DEBUG StateMachine|exit 'NTP:nextGetTimeTimeoutState'
2021-08-17 10:16:35,445 DEBUG StateMachine|entr 'NTP:nextIteratorState'
2021-08-17 10:16:35,445 INFO StateMachine|task 'NTP:nextIteratorState'
2021-08-17 10:16:35,449 DEBUG StateMachine|exit 'NTP:nextIteratorState'
2021-08-17 10:16:35,449 DEBUG StateMachine|entr 'NTP:nextGetTimeTimeoutState'
2021-08-17 10:16:35,449 INFO StateMachine|wait 60000 NTP:nextGetTimeTimeoutState
Run Code Online (Sandbox Code Playgroud)
Ed *_*ton 10
每当您发现自己使用$'{...}'awk 脚本时,您就做错了什么,应该寻求帮助。切勿这样做,因为在编写良好的脚本中从来不需要这样做,并且会导致脚本变得脆弱,因为它会在 awk 看到它之前邀请 shell 解释它的某些部分。
有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。:-)
您正在转义正则表达式元字符以使正则表达式表现得像字符串一样。不要这样做 - 当您想要匹配字符串时,只需使用字符串而不是正则表达式运算符:
awk 'index($0,"DEBUG StateMachine|entr \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;41m" $0 "\033[0m"
}
1' LOG.log
Run Code Online (Sandbox Code Playgroud)
使用s\047而不是's 是因为您无法在 shell 中转义'- 分隔字符串(包括脚本)中的a '。请参阅http://awk.freeshell.org/PrintASingleQuote。
要使用相同颜色突出显示 2 条不同的线,您可以使用:
awk '
index($0,"DEBUG StateMachine|entr \047NTP:nextGetTimeTimeoutState\047") ||
index($0,"DEBUG StateMachine|exit \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;41m" $0 "\033[0m"
}
1' LOG.log
Run Code Online (Sandbox Code Playgroud)
并用 2 种不同颜色突出显示 2 条线:
awk '
index($0,"DEBUG StateMachine|entr \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;42m" $0 "\033[0m"
}
index($0,"DEBUG StateMachine|exit \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;41m" $0 "\033[0m"
}
1' LOG.log
Run Code Online (Sandbox Code Playgroud)
话虽如此,由于您显然正在尝试根据输入的不同部分使用不同的颜色,因此现在最好使用带有捕获组的正则表达式来隔离输入的相关部分,然后只需查看这些部分即可确定每行使用的颜色,以下是我如何使用 GNU awk 作为第三个参数来实现捕获组的 match() :
$ cat tst.awk
BEGIN {
red = "\033[1;41m"
green = "\033[1;42m"
yellow = "\033[1;43m"
blue = "\033[1;44m"
purple = "\033[1;45m"
reset = "\033[0m"
map["nextGetTimeTimeoutState","entr"] = green
map["nextGetTimeTimeoutState","exit"] = red
map["nextIteratorState","entr"] = yellow
map["nextIteratorState","task"] = blue
map["nextIteratorState","exit"] = purple
}
match($0,/(DEBUG|INFO) StateMachine\|(\S+)\s+\047NTP:([^\047]+)\047/,a) {
key = a[3] SUBSEP a[2]
if ( key in map ) {
$0 = map[key] $0 reset
}
}
{ print }
Run Code Online (Sandbox Code Playgroud)
或使用任何 POSIX awk:
$ cat tst.awk
BEGIN {
red = "\033[1;41m"
green = "\033[1;42m"
yellow = "\033[1;43m"
blue = "\033[1;44m"
purple = "\033[1;45m"
reset = "\033[0m"
map["nextGetTimeTimeoutState","entr"] = green
map["nextGetTimeTimeoutState","exit"] = red
map["nextIteratorState","entr"] = yellow
map["nextIteratorState","task"] = blue
map["nextIteratorState","exit"] = purple
}
match($0,/(DEBUG|INFO) StateMachine\|[^[:space:]]+[[:space:]]+\047NTP:[^\047]+\047/) {
split($0,a,/[|[:space:]:\047]+/)
key = a[9] SUBSEP a[7]
if ( key in map ) {
$0 = map[key] $0 reset
}
}
{ print }
Run Code Online (Sandbox Code Playgroud)
无论您使用哪一种,输出都将是:
您不需要中间变量,等等,因为您可以这样做:redgreen
map["nextGetTimeTimeoutState"]["entr"] = "\033[1;42m"
map["nextGetTimeTimeoutState"]["exit"] = "\033[1;41m"
Run Code Online (Sandbox Code Playgroud)
但我发现拥有它们有助于清晰和轻松地进行未来的维护/更新。