我需要从日志中选择一个文本并将该字段有一列存储到新文件中。
例如下面是日志格式
[Mon Dec 07] [error] [client 10.0.0.65] [id "981004"] [file "sample"] [line "84"] [hostname "test"] [uri "/login"] [unique_id "VmVddAo"]
[Mon Dec 07] [error] [client 10.0.0.65] [file "sample"] [line "47"] [id "960015"] [rev "1"] [msg "Request Missing an Accept Header"] [severity "NOTICE"][ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "MISSING_HEADER_ACCEPT"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "test"] [uri "/home"] [unique_id "VmVddQo"]
想要打印如下输出
[Mon Dec 07] [id "981004"] [uri "/login"]
[Mon Dec 07] [id "960015"] [uri "/home"]
我使用 awk 按列打印
grep "Mon Dec 07" filename | sed '/\[[a-zA-Z]/\t&/g' | awk -F'\t' '{print $5}'
But i got the below output
[id "981004"]
[file "sample"]
Because the column are found on different places, for example
[id "981004"] in the 4th column
[id "960015"] in the 6th column
如何使用类似的方式获取值,id 作为键,双引号内是该键的值。选择所有值后,必须将其作为列存储在新文件(csv)中。
感谢 vrs 和 Mirosław Zalewski
#!/bin/bash
search=$1
log=$2
regexp="s/(\[$search[^]]*\]).+(\[id[^]]*\]).+(\[uri[^]]*\]).+/\1 \2 \3/p"
sed -rn "$regexp" $2
&
perl -n -e '$,=" "; @groups = $_ =~ m/(\[.*?\]).*(\[(?:id|uri).*?\]).*((?-2)).*/ ; print @groups, "\n"' /path/to/log/file.log
两者都有效...
最佳答案
您可以使用如下脚本来做到这一点:
#!/bin/bash
search=$1
log=$2
regexp="s/(\[$search[^]]*\]).+(\[id[^]]*\]).+(\[uri[^]]*\]).+/\1 \2 \3/p"
sed -rn "$regexp" $2
您可以将此程序保存到文件(例如 script.sh
),使其可执行(chmod +x script.sh
)并运行 $ ./script.sh "Mon Dec 07"log.txt
这就是脚本的作用:
- 将脚本的第一个参数分配给变量
$search
(要匹配行的文本),将第二个参数分配给变量$log
(日志文件的名称) - 为
sed
创建正则表达式(...)
表示分组\[some text\]
表示方括号内的some text
(它们用 baclslashes 转义)[^...]
表示除...
之外的任何字符,即[^]]
表示除右方括号(正则表达式终止所需)之外的任何字符.+
表示任意正数的任意字符\1
表示我们需要使用第一组中的文本(参见第一个项目符号)sed
的选项-rn
表示分别抑制每行的默认打印和扩展正则表达式的使用
- 在日志文件
log.txt
上使用 sed 正则表达式
希望有帮助。
关于linux - Linux 中的日志文本解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34442247/