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가 보기 전에 쉘이 스크립트의 일부를 해석하도록 초대하므로 스크립트가 불안정해질 수 있습니다.

어떤 사람들은 문제에 직면했을 때 "알겠습니다. 정규식을 사용하겠습니다"라고 생각합니다. 이제 그들은 두 가지 문제를 안고 있습니다.:-)

정규식이 문자열처럼 동작하도록 정규식 메타 문자를 이스케이프하고 있습니다. 이렇게 하지 마세요. 문자열을 일치시키려면 정규식 연산자 대신 문자열을 사용하세요.

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를 세 번째 인수로 사용하여 캡처 그룹의 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"

하지만 이를 사용하면 향후 유지 관리/업데이트를 명확하고 쉽게 만드는 데 도움이 됩니다.

답변2

내가 올바르게 이해했다면 정규식을 사용할 수 있으며작은따옴표의 8진수 표현(\047)이와 같이:

awk '{ sub(/^.*DEBUG StateMachine\|entr \047NTP:nextGetTimeTimeoutState\047/, "\033[1;41m&\033[0m/); print }' LOG.log

여기에 이미지 설명을 입력하세요.

답변3

이것은 단순한 "여러 일치하는 줄 편집"이므로 awk의 강력한 기능이 필요하지 않습니다. 다른 사람들이 지적했듯이 대부분의 문제는 올바르게 인용하는 데 있습니다.

sed를 사용하면 한 줄

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

여기에 텍스트를 입력하면 출력이 아름답게 됩니다. 대부분은 일반 색상 프로필을 사용하지만 직접 작성하는 것도 가능합니다.

먼저 기본값을 사용해 보고 마음에 드는지 확인하세요.

관련 정보