각 줄에서 여러 패턴을 검색하여 새 파일로 출력합니다.

각 줄에서 여러 패턴을 검색하여 새 파일로 출력합니다.

샘플 파일입니다. 실제 로그는 이보다 훨씬 큽니다.

user@linux:~$ cat log.txt 
[24/09/2018:22:41:49 GMT] "PROXY_SERVER_BA2" c-ip=x.x.x.x cs-bytes=1198 cs-categories="Technology/Internet" cs-host=shavar.services.mozilla.com cs-ip=y.y.y.y cs-method=CONNECT cs-uri-path=/ cs-uri-port=443 cs-uri-scheme=tcp cs-User-Agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" cs-username=johndoe dnslookup-time=0 duration=60 rs-status=0 s-action=TCP_TUNNELED

[24/09/2018:17:45:44 GMT] "PROXY_SERVER_AA2" c-ip=x.x.x.x cs-bytes=152450 cs-categories="Business/Economy" cs-host=cvshipping.ups.com cs-ip=z.z.z.z cs-method=CONNECT cs-uri-path=/ cs-uri-port=443 cs-uri-scheme=tcp cs-User-Agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" cs-username=johndoe dnslookup-time=0 duration=268 rs-status=0 s-action=TCP_TUNNELED

[24/09/2018:17:44:03 GMT] "PROXY_SERVER_AA2" c-ip=x.x.x.x cs-bytes=1795 cs-categories="Software Downloads" cs-host=blocklist.addons.mozilla.org cs-ip=z.z.z.z cs-method=CONNECT cs-uri-path=/ cs-uri-port=443 cs-uri-scheme=tcp cs-User-Agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" cs-username=johndoe dnslookup-time=0 duration=61 rs-status=0 s-action=TCP_TUNNELED

[24/09/2018:17:41:44 GMT] "PROXY_SERVER_AA2" c-ip=x.x.x.x cs-bytes=3882 cs-categories="Web Ads/Analytics" cs-host=cebwa.d2.sc.omtrdc.net cs-ip=z.z.z.z cs-method=CONNECT cs-uri-path=/ cs-uri-port=443 cs-uri-scheme=tcp cs-User-Agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" cs-username=johndoe dnslookup-time=0 duration=35 rs-status=0 s-action=TCP_TUNNELED

[20/09/2018:15:48:50 GMT] "PROXY_SERVER_AA2" c-ip=a.a.a.a cs-auth-group=Domain%20Users cs-bytes=227 cs-categories="Web Ads/Analytics;Suspicious" cs-host=data35.adlooxtracking.com cs-ip=b.b.b.b cs-method=CONNECT cs-uri-path=/ cs-uri-port=443 cs-uri-scheme=tcp cs-User-Agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0" cs-username=johndoe duration=0 rs-status=0 s-action=TCP_TUNNELED

[20/09/2018:15:48:35 GMT] "PROXY_SERVER_AA2" c-ip=a.a.a.a cs-auth-group=Domain%20Users cs-bytes=3201 cs-categories="Search Engines/Portals" cs-host=www.google.com cs-ip=b.b.b.b cs-method=CONNECT cs-uri-path=/ cs-uri-port=443 cs-uri-scheme=tcp cs-User-Agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0" cs-username=johndoe dnslookup-time=0 duration=117 rs-status=0 s-action=TCP_TUNNELED
user@linux:~$ 

내 목표는 각 행의 타임스탬프, 카테고리 및 호스트 이름을 가져와 새 파일로 리디렉션하는 것입니다.

타임스탬프(안에 [ ])

user@linux:~$ sed -n 's/^.*\[//p' log.txt | cut -d ']' -f1
24/09/2018:22:41:49 GMT
24/09/2018:17:45:44 GMT
24/09/2018:17:44:03 GMT
24/09/2018:17:41:44 GMT
20/09/2018:15:48:50 GMT
20/09/2018:15:48:35 GMT
user@linux:~$ 

CPU 이름(뒤쪽에 cs-host=)

user@linux:~$ sed -n 's/^.*cs-host=//p' log.txt | cut -d\  -f1
shavar.services.mozilla.com
cvshipping.ups.com
blocklist.addons.mozilla.org
cebwa.d2.sc.omtrdc.net
data35.adlooxtracking.com
www.google.com
user@linux:~$ 

범주( cs-categories="사이 ")

user@linux:~$ sed -n 's/^.*cs-categories="//p' log.txt | cut -d '"' -f1
Technology/Internet
Business/Economy
Software Downloads
Web Ads/Analytics
Web Ads/Analytics;Suspicious
Search Engines/Portals
user@linux:~$ 

sed명령을 하나씩 실행하는 대신 단일 명령을 실행하여 이러한 출력을 생성할 수 있습니까 ?

예상 출력

24/09/2018:22:41:49 GMT    shavar.services.mozilla.com      Technology/Internet
24/09/2018:17:45:44 GMT    cvshipping.ups.com               Business/Economy
24/09/2018:17:44:03 GMT    blocklist.addons.mozilla.org     Software Downloads
24/09/2018:17:41:44 GMT    cebwa.d2.sc.omtrdc.net           Web Ads/Analytics
20/09/2018:15:48:50 GMT    data35.adlooxtracking.com        Web Ads/Analytics;Suspicious
20/09/2018:15:48:35 GMT    www.google.com                   Search Engines/Portals

또한, 이에 대한 더 나은 해결책이 있다면 알려주시기 바랍니다.

답변1

얼마나 멀리 갈 것인가?

sed -r '/^$/d; s/^[^[]*[[]([^]]*)[]].*cs-categories="([^"]*)".*cs-host=([^ ]*) .*/\1\t\3\t\2/' file
24/09/2018:22:41:49 GMT shavar.services.mozilla.com Technology/Internet
24/09/2018:17:45:44 GMT cvshipping.ups.com  Business/Economy
24/09/2018:17:44:03 GMT blocklist.addons.mozilla.org    Software Downloads
24/09/2018:17:41:44 GMT cebwa.d2.sc.omtrdc.net  Web Ads/Analytics
20/09/2018:15:48:50 GMT data35.adlooxtracking.com   Web Ads/Analytics;Suspicious
20/09/2018:15:48:35 GMT www.google.com  Search Engines/Portals

이해합니다?

sed -r '                        use extended regular expressions in the script
/^$/d                           delete empty lines

s/^[^[]*[[]([^]]*)[]].*         look for date time string between square brackets and prepare for 
                                the first "back reference"
cs-categories="([^"]*)".*       look for the string after cs-categories and prepare for second "b r"
cs-host=([^ ]*)                 look for the string after cs-host and prepare for third "b r"
.*/\1\t\3\t\2/                  create output line from back references separated by <TAB> chars.
'

답변2

미리보기 기능이 있는 Perl을 사용하세요. 이렇게 하면 호스트가 클래스 앞인지 뒤인지는 중요하지 않습니다.

perl -lne '
    m(
        ^\[ (.*?) \]                   # match the timestamp
        (?=.* cs-categories= "(.+?)")  # look ahead for the category
        (?=.* cs-host= (\S+) )         # look ahead for the host
    )x
    and print join ",", $1,$2,$3
' log.txt 

답변3

awk를 사용하는 것은 어떻습니까?

awk '{t=""; h=""; c=""; for (i=1; i<=NF; i++) {if ($i ~ /^\[/) {t=$i} if ($i ~/^cs-host=/) {h=$i} if ($i ~ /^cs-categories=/) {c=$i}} if ((t != "") && (h != "") && (c != "")) printf("%s %s %s\n", t, h, c)}' _inputfile_

이것은 귀하가 할 수 있는 일에 대한 대략적인 추정치입니다. 기본적으로 주어진 줄의 각 빈 필드를 반복하고 해당 줄이 특정 문자열로 시작하는지 확인합니다. 그런 다음 해당 필드의 값을 일부 변수에 넣으십시오. 모든 필드가 처리된 후 3개의 필드가 모두 비어 있지 않으면 인쇄됩니다. 그런 다음 입력 파일의 다음 줄로 이동합니다.

문자열의 공백을 처리하기 위해 아무 것도 하지 않습니다. 기존 검사 중 하나를 추가로 검사하여 문자열이 큰따옴표로 끝나는지 확인할 수 있습니다. 그렇지 않은 경우 다음 필드를 변수에 추가합니다.

또한 [, ] 및 "와 같은 항목을 제거하기 위해 하위 문자열을 사용하여 아무 작업도 수행하지 않았습니다. 연습용으로 남겨두겠습니다. :)

관련 정보