使用 grep 和 awk 从日志文件中提取特定行

使用 grep 和 awk 从日志文件中提取特定行

我有一个巨大的日志文件(2000 万行)告诉​​我某些 url 状态是否响应“200 OK”。

我想提取所有状态为“200 OK”的网址,以及附加的文件名。

输入示例:

Spider mode enabled. Check if remote file exists.
--2019-02-06 07:38:43--  https://www.example/download/123456789
Reusing existing connection to website.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Content-Type: application/zip
  Connection: keep-alive
  Status: 200 OK
  Content-Disposition: attachment; filename="myfile123.zip"
  Last-Modified: 2019-02-06 01:38:44 +0100
  Access-Control-Allow-Origin: *
  Cache-Control: private
  X-Runtime: 0.312890
  X-Frame-Options: SAMEORIGIN
  Access-Control-Request-Method: GET,OPTIONS
  X-Request-Id: 99920e01-d308-40ba-9461-74405e7df4b3
  Date: Wed, 06 Feb 2019 00:38:44 GMT 
  X-Powered-By: Phusion Passenger 5.1.11
  Server: nginx + Phusion Passenger 5.1.11
  X-Powered-By: cloud66
Length: unspecified [application/zip]
Last-modified header invalid -- time-stamp ignored.
Remote file exists.

Spider mode enabled. Check if remote file exists.
--2019-02-06 07:38:43--  https://www.example/download/234567890
Reusing existing connection to website.
HTTP request sent, awaiting response... 
  HTTP/1.1 404 Not Found
  Content-Type: text/html; charset=utf-8
  Connection: keep-alive
  Status: 404 Not Found
  Cache-Control: no-cache
  Access-Control-Allow-Origin: *
  X-Runtime: 0.020718
  X-Frame-Options: SAMEORIGIN
  Access-Control-Request-Method: GET,OPTIONS
  X-Request-Id: bc20626b-095f-4b28-8322-ad3f294e4ee2
  Date: Wed, 06 Feb 2019 00:37:42 GMT
  X-Powered-By: Phusion Passenger 5.1.11
  Server: nginx + Phusion Passenger 5.1.11
Remote file does not exist -- broken link!!!

期望的输出:

https://www.example/download/123456789 myfile123.zip

我很想最终理解背后的逻辑。

如果我这样做:

awk '/: 200 OK/{print $0}' file.log

我得到了所有有上下文Status: 200 OK但没有上下文的行。

如果我这样做:

grep -C4 "1 200 OK" file.log

我得到了上下文,但有“噪音”。我想重新排列输出以仅在一行上获取相关信息。

答案1

您需要awk按如下方式使用。首先将 URL 存储在变量中,Status如果OK从后续行获取文件名,则将其存储在该行中。它应该在 GNU 上工作,awk因为该match()函数需要第三个参数来将捕获的组存储在数组中。

awk '/^--/{ url = $NF } 
    /^[[:space:]]+Status/ && $NF == "OK" { getline nextline; match(nextline, /filename="(.+)"/,arr); print url, arr[1] }' file

答案2

i=`awk '/Status: 200 OK/{x=NR+1}(NR<x){getline;print $NF}' filename | awk -F "=" '{print $NF}'| sed 's/"//g'`

awk '{a[++i]=$0}/Status: 200 OK/{for(x=NR-7;x<=NR;x++)print a[x]}' filename | awk -v i="$i" '/https:/{$1=$2="";print $0 " " i}'

输出

https://www.example/download/123456789 myfile123.zip

相关内容