저는 대용량 파일에서 양식 데이터를 추출하려고 했습니다. 매우 구체적인 패턴이 필요하지만 지금까지는 실패했습니다.
로그의 일관된 부분이 있습니다.
Machine info and user info blah blah blah [senderID=60,
ipaddress=/10.1.1.11:8443, serviceIdinList=[13], serviceBitbox=11111,
servicesList= | BeatController | BeatMaker | WaveShow, client=apache,
모든 행은 다음과 같이 표시됩니다.
이 줄에서 다음과 같이 만들어야 합니다.
senderID=60, ipaddress=/10.1.1.11:8443, serviceIdinList=[13],
serviceBitbox=11111, servicesList= | BeatController | BeatMaker | WaveShow,
*"WaveShow" 이후의 모든 내용은 "senderID" 이전의 모든 내용과 마찬가지로 관련이 없습니다.
나는 여기 게시물에서 이 명령을 시도했습니다.
sed -n '/servicesList=/{s/.*servicesList=//;s/\S*=.*//;p}'
하지만 인쇄만 됩니다
servicesList= | BeatController | BeatMaker | WaveShow
grep 및 sed를 사용하여 정규 표현식을 사용하여 일부 반복에서 수정을 시도했지만 진행되지 않았습니다.
답변1
원하는 작업이 와 포함 사이의 모든 것을 출력하는 것이라면 senderID=
다음 WaveShow,
명령이 필요합니다 sed
.
sed -n 's/.*\(senderID=.*WaveShow,\).*/\1/p'
이렇게 하면 \(
및 대괄호를 사용하여 \)
이 두 문자열 사이의 모든 내용을 캡처하고 \1
( \2
캡처가 더 있는 경우 등)을 사용하여 출력합니다.
선행은 .*
"탐욕적"입니다. 즉, senderID=
문자열이 입력에 두 번 나타나면 첫 번째 문자열이 삭제됩니다. 이것이 원하는 것이 아니라면 sed
이 도구는 이를 처리할 수 있는 올바른 도구가 아닙니다 perl
. 명령은 다음과 같습니다.
perl -ne 'print if s/.*?(senderID=.*WaveShow,).*/$1/'
-n
"각 입력 줄에 대해 루프를 실행하고 루프 끝 부분에 줄을 인쇄하지 않음"을 의미합니다. -e
루프 내에서 실행할 표현식을 지정합니다.
?
변경 후에는 가능한 한 적게 일치하십시오(예: 탐욕스럽지 않게 일치) .*
. *
괄호는 Perl이 부분을 그룹화하고 캡처하도록 하며, 그런 다음 $1
첫 번째 캡처, $2
두 번째 캡처 등 으로 사용할 수 있습니다.
그러나 이것은 Perl에서 이를 수행하는 최선의 방법은 아닙니다. 이는 불필요하게 문자열을 변경하고, 텍스트를 캡처하고, 인쇄하는 작업을 포함하지 않기 때문에 훨씬 더 좋습니다.
perl -ne 'print "$1\n" if /(senderID=.*WaveShow,)/'
Perl에는 아마도 더 효율적으로 이를 수행할 수 있는 더 많은 방법이 있을 것입니다.
답변2
후행 쉼표가 필요합니까?
그렇지 않은 경우 다음과 같이 작동합니다.
grep senderID filename | cut -d '[' -f 2- | cut -d ',' -f -5
산출:
senderID=60, ipaddress=/10.1.1.11:8443, serviceIdinList=[13], serviceBitbox=11111, servicesList= | BeatController | BeatMaker | WaveShow