파일에 여러 기호가 포함된 경우 두 문자열 사이를 추출하는 방법

파일에 여러 기호가 포함된 경우 두 문자열 사이를 추출하는 방법

저는 대용량 파일에서 양식 데이터를 추출하려고 했습니다. 매우 구체적인 패턴이 필요하지만 지금까지는 실패했습니다.
로그의 일관된 부분이 있습니다.

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

관련 정보