私はawkスクリプトやスクリプトを生成する別の方法を試しました。
日付と時刻の変数(ただし、特定の単語を含む)を含むログファイルの特定の行に、特定の色でアンダースコアを表示したいと思います。
awkで同様のものを作成しましたが、特定のフレーズだけを強調し、日付と時刻を強調しません。さらに、日付と時刻、またはその単語を含む行全体を強調することは可能ですか?
awk $'{ gsub(" DEBUG StateMachine\|entr \'NTP:nextGetTimeTimeoutState'", "\033[1;41m&\033[0m");
print }' LOG.log
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
答え1
$'{...}'
awkスクリプトを使用する自分を見つけるたびに何かが間違っているので、助けが必要です。これをしないでください。よく書かれたスクリプトでは絶対に必要ではなく、awkが表示する前にシェルがスクリプトの一部を解釈するように招待するため、スクリプトが不安定になる可能性があります。
何人かの人々が問題に直面したとき、「わかりました。正規表現を使います」と思います。今、彼らは2つの問題を抱えています。:-)
私は正規表現が文字列のように動作するように正規表現メタ文字をエスケープしています。これをしないでください。文字列を一致させるには、正規表現演算子の代わりに文字列を使用してください。
awk 'index($0,"DEBUG StateMachine|entr \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;41m" $0 "\033[0m"
}
1' LOG.log
シェルで区切られた文字列(スクリプトを含む)では、-aをエスケープできないため、sの\047
代わりにsを使用してください。バラより'
'
'
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
そして、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
しかし、入力のさまざまな部分に基づいてさまざまな色を使用したいので、キャプチャグループと一緒に正規表現を使用して入力の関連部分を分離し、その部分を見て決定することをお勧めします。色を使用してGNU awkを3番目の引数として使用して、キャプチャグループの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 }
または、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 }
どちらを使用しても、出力は次のようになります。
あなたはしません必要次のように中間変数などred
をgreen
使用できます。
map["nextGetTimeTimeoutState"]["entr"] = "\033[1;42m"
map["nextGetTimeTimeoutState"]["exit"] = "\033[1;41m"
ただし、これを使用すると、将来のメンテナンス/アップデートを明確かつ簡単に作成するのに役立ちます。
答え2
正しく理解したら正規表現を使うことができ、一重引用符の8進数表現(\047)
このように:
awk '{ sub(/^.*DEBUG StateMachine\|entr \047NTP:nextGetTimeTimeoutState\047/, "\033[1;41m&\033[0m/); print }' LOG.log
答え3
これは単純な「複数のマッチ行編集」なので、awkの強力な機能は必要ありません。他の人が指摘したように、ほとんどの問題は正しく引用されています。
sedを使用すると、1行
sed "/DEBUG StateMachine|entr 'NTP:nextGetTimeTimeoutState'/s/.*/"$'\e[[1;41m&\e[0m'/
または3で
PAT=" DEBUG StateMachine|entr 'NTP:nextGetTimeTimeoutState'"
TO=$'\e[[1;41m&\e[0m'
sed "/$PAT/s/.*/$TO/"
答え4
については他の方法colorize
、これに類似または類似のパッケージがあります。ccze
ここにテキストを入力すると、出力が美しくなります。ほとんどは通常のカラープロファイルを使用しますが、自分で作成することも可能です。
まず、デフォルト値を試して、気に入っていることを確認してください。