실제 로그는 다음과 같습니다.
2016-06-19 22:08:09 [213917] 1bEgCe-000tZR-E9 ** [email protected] ([email protected]) <[email protected]> F=<[email protected]> P=<[email protected]> R=lookuphost T=remote_smtp H=mailin-01.mx.aol.com [64.12.88.131]:25 I=[36.23.21.11]:60147: SMTP error from remote mail server after initial connection: 554- (RTR:BL) https://postmaster.aol.com/error-codes#554rtrbl\n554 Connecting IP: 36.23.21.11
2016-06-20 01:03:22 [516458] 1bEiwD-001zt7-IY ** [email protected] ([email protected]) <[email protected]> F=<[email protected]> P=<[email protected]> R=lookuphost T=remote_smtp H=mailin-02.mx.aol.com [64.12.88.163]:25 I=[36.23.21.14]:47630: SMTP error from remote mail server after initial connection: 554- (RTR:BL) https://postmaster.aol.com/error-codes#554rtrbl\n554 Connecting IP: 36.23.21.14
2016-06-20 09:29:46 [256975] 1bEqpT-0014jI-HV ** [email protected] F=<[email protected]> P=<[email protected]> R=dkim_lookuphost T=dkim_remote_smtp H=mailin-04.mx.aol.com [64.12.88.132]:25 I=[36.23.21.11]:43705: SMTP error from remote mail server after initial connection: 421 DYN:T2 https://postmaster.aol.com/error-codes#554rtrbl\n554 Connecting IP: 36.23.21.11
2016-06-20 11:41:34 [413114] 1bEstm-001jSC-Ic ** [email protected] F=<[email protected]> P=<[email protected]> R=dkim_lookuphost T=dkim_remote_smtp H=mailin-02.mx.aol.com [64.12.91.195]:25 I=[36.23.21.14]:48714: SMTP error from remote mail server after initial connection: 421 DYN:T1 https://postmaster.aol.com/error-codes#554rtrbl\n554 Connecting IP: 36.23.21.14
내가 얻고 싶은 것:
Timestamp EmailTo: EmailFrom: IPAddress: ErrorCodes:
2016-06-19 [email protected] [email protected] 36.23.21.11 554- (RTR:BL)
2016-06-20 [email protected] [email protected] 36.23.21.14 554- (RTR:BL)
2016-06-20 [email protected] [email protected] 36.23.21.11 421 DYN:T2
2016-06-20 [email protected] [email protected] 36.23.21.14 421 DYN:T1
다음 명령에서 처음 세 개의 필드를 추출했습니다.
echo -e "Timestamp\t\tEmailTo:\t\tEmailFrom:\t\t\t\t\t\t\t\tIPAddress:\tErrorCodes:" && awk 'NF>6 { d=6 ; while ( ! ($d ~ /^F=/ ) ) d++ ; printf "%s\t%s\t%s\n",$1,$6,substr($d,4,length($d)-4) ;} ' logs | column -t
모두에게 감사하지만 다음을 통해 해냈습니다.
echo -e "Timestamp:\tEmailTo:\tEmailFrom:\t\tIPAddress:\tErrorCodes:" && awk 'NF>6 { d=6 ; while ( ! ($d ~ /^F=/ ) ) d++ ; print "%s\t%s\t%s\t%s\t%s\t%s\n",$1,$6,substr($d,4,length($d)-4),$NF,$(NF-5)$(NF-4) ; }' oops | column -t| grep -v "%s"
답변1
당신은 awk를 사용하는 올바른 길을 가고 있었습니다. 로그를 읽고 필드를 탭으로 구분하여 출력하는 스크립트를 작성해야 합니다. 그런 다음 열 명령을 사용하여 열을 다시 정렬합니다.
extract.awk²:
BEGIN {OFS="\t"; print "Timestamp\tEmailTo:\tEmailFrom:\tIPAddress:\tErrorCodes:"}
{print $1, $6, $7, $NF, $(NF-5)}
그런 다음 다음 명령으로 실행하십시오.
awk -f extract.awk logs | column -t -s '^I'
여기서는 '^I'
따옴표로 묶인 실제 탭을 나타냅니다.
유일하게 까다로운 부분은 로그의 오류 메시지를 처리하는 것이었습니다. 이는 단어 수가 가변적일 수 있습니다. IP 및 오류 코드 필드의 오른쪽부터 열을 계산하여 문제를 해결했습니다.
출력은 다음과 같습니다.
Timestamp EmailTo: EmailFrom: IPAddress: ErrorCodes:
2016-06-19 [email protected] ([email protected]) 36.23.21.11 554-
2016-06-20 [email protected] ([email protected]) 36.23.21.14 554-
2016-06-20 [email protected] F=<[email protected]> 36.23.21.11 421
2016-06-20 [email protected] F=<[email protected]> 36.23.21.14 421
어느 것이 어느 것인지 지정하지 않았기 때문에 입력 열에 대해 잘못 추측했을 수 있습니다. 세 번째 열의 이메일 주소를 정리하려면 awk에 너무 깊이 빠져 있을 수 있으므로 이제 사용을 고려해야 할 때입니다. 파이썬이나 펄.
¹또는 데이터에 포함되지 않는 한 원하는 출력 구분 기호를 사용하세요. 그런 다음 이를 -s
에 대한 인수 로 사용하십시오 column
.
²@Kusalananda가 지적했듯이 awk 스크립트를 한 줄로 작성할 이유가 없습니다. 그의 버전은 다음과 같습니다.
BEGIN {
OFS="\t";
print "Timestamp\tEmailTo:\tEmailFrom:\tIPAddress:\tErrorCodes:";
}
{
print $1, $6, $7, $NF, $(NF-5);
}
저는 한 줄짜리를 좋아합니다.