실패한 전자 메일에 대한 전자 메일 서버 보고서를 저장하는 사서함 파일을 구문 분석하고 있습니다. 잘못된 전자 메일 주소를 추출하고 싶습니다. 로그 파일은 다음과 같습니다.

...some content... The mail system <[email protected]>: host mx1.hotmail.com[65.54.188.94] said: 550 Requested action not taken: mailbox unavailable (in reply to RCPT TO command) ...some content... The mail system <[email protected]>: host viking.optimumpro.net[79.101.51.82] said: 550 Unknown user (in reply to RCPT TO command) ...some content... The mail system <[email protected]>: host mta5.am0.yahoodns.net[74.6.140.64] said: 554 delivery error: dd This user doesn"t have a yahoo.com account ([email protected]) [0] - mta1172.mail.sk1.yahoo.com (in reply to end of DATA command) ...etc. 

이메일 주소는 “The mail system”이라는 줄 뒤에 2 줄이 나옵니다. . 이와 같이 grep을 사용하면 “The mail system”줄과 다음 두 줄이 나타납니다.

grep -A 2 "The mail system" mbox_file 

하지만 제거하는 방법을 모르겠습니다. “메일 시스템”줄과이 출력의 두 번째 빈 줄. PHP / Perl / Python 스크립트를 작성하여 수행 할 수 있다고 생각하지만 grep 또는 다른 표준 도구로 이것이 가능한지 궁금합니다. -B 매개 변수에 음수 오프셋을 지정하려고했습니다.

grep -A 2 -B -2 "The mail system" mbox_file 

하지만 grep이 다음과 같이 불평합니다.

grep: -2: invalid context length argument 

grep으로이 작업을 수행하는 방법이 있습니까?

댓글

  • -B는 -A처럼 숫자를 허용하며 일치 전의 이전 줄.
  • 예, 맞습니다.하지만 밀라노 는 ' 전의 일치 항목에 관심이 없습니다 .. . 문제는 -A와 -B가 양수 값만 허용한다는 것입니다. 어떤 경우에도 -A와 -B는 서로에 대해 ' 사용할 수 없습니다. , 그가 시도한대로.
  • 흠, 확인하기 위해 : 그것들은 주어진 파일에서 (직접) 추출하지 않은 더미 주소입니다. 맞습니까?
  • @Matthieu M. 아니요, 실제 로그 파일에서 가져온 것입니다. 어쨌든 유효하지 않은 주소이기 때문에 ' 유효 할 수있는 더미 주소를 발명하는 요점이 무엇인지 생각했습니다.
  • stackoverflow.com/questions/8101701/…

답변

grep 만 사용하여 문제를 해결하는 가장 간단한 방법은 끝에 반전 된 grep를 하나 더 파이프하는 것입니다. . 예 :

grep -A 4 "The mail system" temp.txt | grep -v "The mail system" | grep -v "^\d*$" 

Answer

grep를 사용하여 sed

sed -n "/The mail system/{n;n;p}" 

언제 “The mail system”이 포함 된 줄을 찾고 n;n;를 통해 다음 줄을 두 번 읽고 이전 줄을 그대로 삭제합니다.
그러면 세 번째 줄이 남습니다. sed “의 p 명령을 통해 인쇄되는 패턴 공간에있는 그룹 .. 선행 -n 옵션은 다른 모든 인쇄를 방지합니다. .

다음 두 줄도 인쇄하려면 다음 및 인쇄 n;p 두 번 더 사용하면됩니다.

sed -n "/The mail system/{n; n;p; n;p; n;p}" 

필요한 행에 대한 다음 행 읽기를 누적하여 하나의 블록으로 인쇄 할 수 있습니다. pN는 다음 줄을 읽고 패턴 공간에 추가합니다.

다음은 최종 압축 버전입니다 …

sed -n "/The mail system/{n;n;N;N;p}" 

grep wouuld 출력과 유사한 그룹 구분자 가 필요한 경우 sed “의 insert 명령을 사용할 수 있습니다. i (한 줄의 마지막 명령이어야 함) …

다음은 그룹 구분자 를 포함하는 구문입니다. / p>

sed -n "/The mail system/{n;n;N;N;p;i-- }" > output-file # or | ... 

다음은 첫 번째 일치 결과입니다.

<[email protected]>: host mx1.hotmail.com[65.54.188.94] said: 550 Requested action not taken: mailbox unavailable (in reply to RCPT TO command) -- 

댓글

  • +1. 감사합니다. '이 경우 필요하지 않지만 ' 더 복잡한 내용을 처리해야 할 경우를 대비하여이 북마크를 유지합니다.
  • 정답입니다!

답변

grep -A 2 -B -2 "The mail system" mbox_file 

-B는 이전 줄용이므로-음수 값을 제공 할 필요가 없습니다.

grep -A 2 -B 2 "The mail system" mbox_file # This will work please check 

댓글

  • 질문에 대한 답변이 아닙니다. -A 2 -B 2는 컨텍스트 앞의 두 줄에서 컨텍스트 뒤의 두 줄까지 인쇄합니다. 문제는 컨텍스트 뒤 2 줄에서 컨텍스트 뒤 4 줄까지 인쇄하는 것입니다.

Answer

I “엄격한 제약 조건입니다. grep을 한 번만 호출하면 수행 할 수 없습니다.

grep -A 2 "The mail system" mbox_file | tail -n +3 
  • grep : 줄을 찾아 그 뒤에 2 줄을 출력합니다.
  • 꼬리 : 처음 두 줄을 잘라냅니다 (즉, 세 번째 줄에서 시작).

설명

  • 이는 일치하는 행이 하나 일 때만 작동합니다. 이는 아마도 질문이 요구하는 내용이 아닐 것입니다.
  • 그것은 질문이 요구 한 내용이 아닙니다. 제 현재 상황에서 저를 도와줍니다 :-).
  • @ daniel.neumann 알아요,하지만 저는 정확히 당신의 입장이었고 다른 사람들이 ' Google-fu가 여기도 이끄세요.

답변

처음 두 줄을 제거하려면

sed "1,2d" 

예 :

 grep -A 2 "The mail system" mbox_file | sed "1,2d"  

댓글

  • 패턴이 여러 번 발생한다는 사실을 놓쳤습니다. “The mail system”이 4, 14, 24, 34,… 줄에 나타나면 OP는 6, 16, 26, 36,… 줄을보고 싶어합니다. 귀하의 대답은 6, 14-16, 24-26, 34- 36,….

Answer

Perl을 사용하여 정규식 일치 다음 1 줄을 인쇄합니다.

perl -ne "print if( (/The mail system/ && ($end=1))..!$end-- )" 

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다