awkやその他の方法による線の検索と色の指定

awkやその他の方法による線の検索と色の指定

私は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 }

どちらを使用しても、出力は次のようになります。

ここに画像の説明を入力してください。

あなたはしません必要次のように中間変数などredgreen使用できます。

    map["nextGetTimeTimeoutState"]["entr"] = "\033[1;42m"
    map["nextGetTimeTimeoutState"]["exit"] = "\033[1;41m"

ただし、これを使用すると、将来のメンテナンス/アップデートを明確かつ簡単に作成するのに役立ちます。

おすすめ記事