나는 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 }
어느 것을 사용하든 출력은 다음과 같습니다.
당신은하지 않습니다필요다음과 같이 중간 변수 등 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를 사용하면 한 줄
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
여기에 텍스트를 입력하면 출력이 아름답게 됩니다. 대부분은 일반 색상 프로필을 사용하지만 직접 작성하는 것도 가능합니다.
먼저 기본값을 사용해 보고 마음에 드는지 확인하세요.