끊임없이 채워지는 로그 파일이 있는데, 그 이름이 logfile.txt라고 가정하겠습니다. 이 로그 파일에서는 bash 명령을 사용하여 같은 줄에 다른 문자열이 포함된 단일 줄의 하위 문자열을 지속적으로 캡처하려고 합니다.
다음은 로그 파일의 한 줄 예입니다.
2023-08-31 09:56:39,925 [G_M80T72|utx:0:ffffac17000b:45253299:64ec7753:79cb0e|chnl:LN1_CRYPTO_IN_MQ_REQ_AMP|id:196010175121000000000002134] WARN transaction.GeneralTransactionFailureException - GeneralTransactionFailureException Gateway.Transaction[196010175121000000000000067v1], StatusReason[ProcessingFailed/PayloadIntegrityCheckFailed]
줄에 가 포함될 때마다 string1 LN1
과 string2를 캡처하고 싶습니다.CRYPTO_IN_MQ_REQ_AMP
PayloadIntegrityCheckFailed
String1 앞에는 항상 chnl:
'가 오고, string2 앞에는 항상 파이프가 옵니다. 2개의 문자열은 항상 밑줄로 구분됩니다(그러나 string2에는 밑줄도 포함될 수 있습니다) 제 경우에는 string1=LN1이지만 다음과 같을 수 있습니다. {모든 알파벳 문자}LN{모든 숫자} String2는 문자와 숫자로 구성될 수 있습니다
string1과 string2를 캡처한 후 이를 다른 명령의 매개변수로 사용합니다. 예를 들면 다음과 같습니다.
{another_command} string1 string2
물론 새 항목만 캡처해야 하며 전체 로그를 계속해서 스캔하고 싶지 않고 새 줄만 스캔하고 싶기 때문에 tail -f
파일을 먼저 수행한 다음 sed 매직과 정규식을 사용하고 싶습니다.
진행하는 방법을 알고 있나요?
답변1
$ sed -e '/PayloadIntegrityCheckFailed/!d' -e 's/.*chnl:\([^|]*\).*/\1/' -e 's/_/ /' file
LN1 CRYPTO_IN_MQ_REQ_AMP
위의 명령은 sed
문자열을 포함하지 않는 모든 줄을 삭제합니다 PayloadIntegrityCheckFailed
. 나머지 줄은 chnl:
다음 문자 |
사이의 내용 으로 대체됩니다 . 문자열의 첫 번째 밑줄이 공백 문자로 바뀌고 결과가 출력됩니다.
두 번째 sed
표현식은 s/.*chnl:\([^|]*\).*/\1/
아마도 두 개의 더 간단한 치환으로 대체될 수 있습니다. s/.*chnl://
그리고 이는 엄밀히 말하면 동일한 것은 아니지만 하위 문자열 뒤에 문자 s/|.*//
가 있는 예제 데이터에 동일한 효과를 갖습니다 .chnl:
|
sed
tail -f
지속적인 작업을 위해 파일 대신 명령을 사용하여 출력을 읽을 수 있습니다 . 이 경우 가능하면 라인 버퍼링 작업 sed
(비표준 -u
옵션) 을 사용할 수도 있습니다.
tail -f /var/log/some.log | sed -u -e ...as before...
이러한 문자열을 변수로 읽고 다른 프로세스에서 사용하려면 루프에서 위 파이프의 출력을 읽을 수 있습니다 while
.
tail -f ... | sed ... |
while read -r first_string second_string; do
some-command "$first_string" "$second_string"
done
답변2
문제를 해결하는 방법에는 cat, grep, awk 등 각기 다른 도구를 사용하는 여러 가지 방법이 있습니다.
"부분 문자열을 지속적으로 캡처하고 싶습니다"라는 귀하의 진술을 고려하면 일치하는 tail -f
항목을 화면에 표시하거나 파일에 쓰는 것이 올바른 접근 방식이라고 생각합니다.
화면에 인쇄하려면:
tail -f /path/to/your/file.log | grep "PayloadIntegrityCheckFailed" | grep -E "LN1.*CRYPTO_IN_MQ_REQ_AMP"
결과를 파일에 저장하려면:
tail -f /path/to/your/file.log | grep "PayloadIntegrityCheckFailed" | grep -E "LN1.*CRYPTO_IN_MQ_REQ_AMP" >> /tmp/some_file.txt
설명하다:
tail -f
file.log에 추가된 새로운 라인을 실시간으로 지속적으로 출력합니다.grep "PayloadIntegrityCheckFailed"
새 줄을 필터링하고PayloadIntegrityCheckFailed
해당 문자열을 포함하지 않는 줄을 무시하세요.- grep -E는 grep을 REGEXP 모드로 전환합니다.
- 검색 패턴은
"LN1.*CRYPTO_IN_MQ_REQ_AMP"
해당 문자열을 포함하는 모든 줄LN1
뿐만 아니라CRYPTO_IN_MQ_REQ_AMP
줄 앞부분의 다른 위치도 포착합니다.
귀하의 예에서는 문자열이 LN1
"_" 문자로 연결된 것으로 나타납니다. CRYPTO_IN_MQ_REQ_AMP
그래도 귀하의 질문에서 명확하게 설명하지 않았기 때문에 두 문자열을 원하는 수의 ".*" 문자로 구분했습니다.