Regex 通过awk检索日志模式

Regex 通过awk检索日志模式,regex,awk,Regex,Awk,我想从以下日志中检索日期、5 URI长度、ab和cde: 10.10.10.10 - - [26/Oct/2020:19:50:13 +0000] "GET /five/six/seven/eight/nine/en?from=1603738800&to=1603785600ncludedInRange=false HTTP/1.1" 200 255441 "-" "Opera com.test.super/1.10.4;11072 (L

我想从以下日志中检索日期、5 URI长度、ab和cde:

10.10.10.10 - - [26/Oct/2020:19:50:13 +0000] "GET /five/six/seven/eight/nine/en?from=1603738800&to=1603785600ncludedInRange=false HTTP/1.1" 200 255441 "-" "Opera com.test.super/1.10.4;11072 (Linux;Neon KNWWWfj;0,02.2)" "10.10.10.10""f799b6b9-747f-4f22-a1bf-4b7de885fc60""-" "-" "-" "-"ab=0.110 cde=0.102
11.1.1.1 - - [26/Oct/2020:19:50:14 +0000] "GET /one/two/three/four/five/en HTTP/1.1" 200 2832 "-" "Opera com.test.super/1.10.4;11072 (Linux;Neon KNWWWfj;0,02.2)" "11.1.1.1""19a8ee3c-9cb3-4ba6-9732-eb4923601e92""-" "-" "-" "-"ab=0.111 cde=0.112
e、 g

我尝试了以下命令,但只得到了部分命令。你能帮忙吗

awk '{print $4 "\t" $7 "\t" $(NF-1),"\t",$NF}' |sed 's/"-"//g'

基于@Ed Morton,但将FS设置为5个部分:

$ awk -v FS='[[]|\\+[[:digit:]]+[]]|GET |/en|"+-"' '{print $2,$4,$NF}' file
26/Oct/2020:19:50:13  /five/six/seven/eight/nine ab=0.110 cde=0.102
26/Oct/2020:19:50:14  /one/two/three/four/five ab=0.111 cde=0.112

更新。
感谢@Ed Morton。

为什么第二行没有输出?您和海报在解析非常相似的输入文件时应该交谈。在shell中,您应该始终在字符串和脚本周围使用单引号,除非您需要双引号使shell解释它,例如,对于全局搜索、文件名扩展、变量扩展,如果你遵循这条规则,它会使你所有的代码更加简洁和健壮。在这种情况下,您不需要在
FS
声明中使用几乎同样多的反斜杠-现在您要求shell解释
-vfs“…”
中的字符串,方法是用双引号将其括起来,然后转义其中的所有内容,以阻止shell解释它,这毫无意义,只需执行
-vfs='''.
-F'.
。也没有理由将
-
放在括号表达式中,或在动态regexp中转义
/
,它们都已经是文本字符。因此,如果代码总体上是对的还是错的,请输入idk,但我认为您只需要指定FS是
-F'[]|\+[[:digit:][]+[]]| GET |/en |“+-”
@Ed Morton.是的,我明白了,但是有没有具体的文档或指南,包括在awk中正确使用regexp的语法特性?这会有所帮助。awk只实现POSIX ERE,所以请参见POSIX标准。awk允许计算regexp(由字符串和/或变量组成)以及文字regexp-这在awk标准和所有手册页中都有记录,只是意味着您需要知道它被解析了两次,因此需要额外的转义。一些版本的awk对POSIX有一些小的扩展,例如
\
单词边界或
\s/\code>速记,例如GNU awk,因此请参阅手册页了解更多信息详细信息请访问awk版本。否则没有特殊性。
$ awk -F'[][[:space:]"]+' -v OFS='\t' '{match($7,"(/[^/]*){5}"); print $4, substr($7,1,RLENGTH), $(NF-1), $NF}' file
26/Oct/2020:19:50:13    /five/six/seven/eight/nine      ab=0.110        cde=0.102
26/Oct/2020:19:50:14    /one/two/three/four/five        ab=0.111        cde=0.112
$ awk -v FS='[[]|\\+[[:digit:]]+[]]|GET |/en|"+-"' '{print $2,$4,$NF}' file
26/Oct/2020:19:50:13  /five/six/seven/eight/nine ab=0.110 cde=0.102
26/Oct/2020:19:50:14  /one/two/three/four/five ab=0.111 cde=0.112