我有日志文件,需要从具有 404d 的 GET 请求中提取 URL
我用过 :
grep 404 testfile.txt | cut -f 2 -d '"' | cut -f 2 -d '/' | cut -f 1 -d ' ' | sort -u
不建议像这样将剪切命令放在一起,我可以将它们组合成一行吗?例如从第3个“/”和第6个“”开始剪切。
日志文件示例:
ip - - [12/Dec/2019:13:18:00 +0000] "GET /test.html HTTP/1.1" 200 710 "-" "python-requests/2.18.4"
ip - - [12/Dec/2019:13:18:00 +0000] "GET /403dz2.html HTTP/1.1" 404 492 "-" "python-requests/2.18.4"
结果 :
403dz2.html,
is0pmq.html,
iw30ce.html,
nbk0px.html,
答案1
像您所做的那样将命令管道在一起并没有什么问题cut
,但是,您应该意识到,在大型输入上可能有更有效的方法来执行此操作。这是因为在您的示例中,输入文件在输出到终端之前必须由命令处理 5 次(一次用于grep
过滤,三个单独的cut
解析命令,一次 to sort
)。使用更少的管道可能提高性能,但这最终取决于命令本身以及它们执行的操作(即,三个快速且简单的操作比一个大型高计算操作更快)。如果输入数据相对较小,则无论您使用管道方法还是使用以下方法之一都没有区别。
笔记:与OP的原始命令链相比,我不确定以下示例的效率或速度。根据用例,有些可能比其他“更好”。
使用awk
: (受到推崇的)
awk '$9=="404" {print substr($7,2)","}' testfile.txt
上面与 Romeo 的答案类似,但是这还从日志输出中的文件名中删除了前面的斜杠,并在末尾添加了逗号,以匹配您想要的结果。awk
是一个逐行解析输入数据(默认情况下)的命令,在空格分隔符上分割每一行(默认情况下)。此命令检查第 9 个字段(HTTP 响应代码)404
,如果匹配,则获取第 7 个字段从第 2 个字符到末尾 ( ) 的子字符串,并在打印输出之前substr($7,2)
在该字段后面附加一个逗号 ( )。","
您可以阅读更多有关awk
这里。
使用您的示例与 1 cut
+ sed
:
grep '" 404' testfile.txt | cut -d' ' -f7 | sed 's/\///; s/$/,/'
您不需要三个单独的剪切命令来提取文件名,在使用空格分隔符时只需要一个。该cut
命令将拉动绳子/403dz2.html
。sed
然后将删除前面的斜杠 ( s/\///
),然后在末尾添加一个逗号 ( s/$/,/
)。什么sed
是实际上这里所做的就是替代。字符串s/replace this/with this/
指示用第二个sed
字符串 ( ) 替换第一个字符串replace this
( with this
)。第一个替换命令指示不sed
替换/
任何内容,第二个命令表示将行尾 ( $
) “替换”为,
。您可以阅读更多有关sed
这里。另请注意,我正在grep
for " 404
,这有点 hacky,但它不会grep
返回 404 出现在其他地方的行(如文件名、文件大小、日期等)。
使用perl
:
grep '" 404' testfile.txt | perl -lane 'print substr($F[6],1).","'
这与示例类似awk
,同时用于grep
过滤输入。使用与 相同的想法awk
,我们打印第 7 个字段 ( substr($F[6],1)
) 的子字符串,并向该输出附加一个逗号 ( .","
)。请注意,perl 从 0 开始计数,而 awk 从 1 开始计数,因此我们使用$F[6]
in来拉取awk 中使用perl
as 的第 7 个字段。$7
说明书perl
可以找到这里。
答案2
您是否尝试使用分隔符空格 ( ) 进行过滤?
awk '$9=="404" {print $7}' testfile.txt|sort -u
或者用这个:
grep 404 testfile.txt | cut -f 7 -d ' '|sort -u
PS 例如,当下载长度为 404 字节时,第二种方式将匹配。或者年份包含 404 字符串。或者请求的 URL 包含此字符串。
答案3
使用awk
命令:
awk -F '[ /]' '/ 404 / {print $10|"sort -u"}' testfile.txt
解释:
-F '[ /]'
:使用空格“ ”和正斜杠“/”作为分隔符。 (多个分隔符)/ 404 /
:仅匹配包含“ 404 ”的行。就像grep " 404 " testfile.txt
作品一样。
笔记:“404”前后有一些间距。
这消除了可能出现在 URL 而不是响应代码中的任何误报匹配。例如,以下行将不会被匹配:
ip - - [12/Dec/2019:13:18:00 +0000] "GET /test404.html HTTP/1.1" 200 710 "-" "python-requests/2.18.4"
笔记:test404.html网址包含404但响应代码是200。因此需要在“404”之前和之后留出间距。
print $10
:使用空格和斜杠作为分隔符,显示第10个字段。| sort -u
:对结果进行排序,仅取一个有重复的实例。(即显示唯一行)testfile.txt
:包含要匹配的行的文件。
笔记:假设还有其他行404
但不感兴趣,您可以使用以下方法收紧匹配:
awk -F '[ /]' '/GET.* 404 / {print $10|"sort -u"}' testfile.txt
修改内容:
/GET.* 404 /
:仅匹配包含“GET
后接其他内容,然后是404
”的行
最后:
如果您希望 URL 前有斜杠,请使用:
awk '/ 404 / {print $7|"sort -u"}' testfile.txt
如果您想在 URL 后添加逗号,请使用:
awk -F '[ /]' '/ 404 / {print $10","|"sort -u"}' testfile.txt
如果您想要 URL 之前的斜杠和 URL 之后的逗号,请使用:
awk '/ 404 / {print $7","|"sort -u"}' testfile.txt