我需要分析日志,我的最终用户必须能够以格式化的方式看到它们,如下所述,我的日志本质是key
变量将位于不同的位置,而不是基于应用程序的固定列,因为这些日志格式来自不同的应用程序。
"thread"t1"key1":"value1"key2":"value2",……"key15":"value15"
我有一种方法来分割和切割它,只分析特定的键,使用下面的
cat file.txt | grep 'value1' | cut -d',' -f2,7,8-
这是我能够获得的命令,要求是我需要grep所有具有'key1'作为'value1'的日志,而这个value1将最有可能在所有日志中是唯一的,所以我直接使用grep,如果需要,我可以使用grep来选择键和值字符串,但我面临的主要问题是,部分是切割后的。我想在这些行中只选择key2, key7, key8
,但key2, key7, key8
可能不会像这样出现在相同的列号中,key2
甚至可能出现在第3列或第4列,或者在key7
/key8
之后,所以我想根据key
的值进行选择,并得到准确的
"key2";value2"; "key7"; "value7"; "key8:value8">
最终用户对它们出现的顺序并不特别挑剔,他们只需要显示每一行中的这些键。有人能帮帮我吗?我再次尝试使用awk/grep进行管道匹配,但它们仍然匹配整行,而不仅仅是列
输入是
{"@timestamp"2021 - 08 - 05 - t06:38:48.084z","level":"INFO","thread":"main","logger":"className1","message":"消息1";}{"@timestamp"2021 - 08 - 05 - t06:38:48.092z","level":"DEBUG","thread":"main","logger":"className2","message":"消息2"}{"@timestamp"2021 - 08 - 05 - t06:38:48.092z","level":"DEBUG","thread":"thead1","logger":"className2","message":"消息2"}
我基本上希望我的输出更像,只找到"thread":"main"
行,只打印"logger"
和"message"
的键和值对于每一行匹配,因为其他键和值与我无关。我的文件中有超过15到16个键,我的键位置可以交换,比如"message"
可能是第一个出现,"logger"
可能是第二个出现在一些日志文件中。当然,钥匙只是一个例子,我想找到的真正的钥匙不仅仅是"logger"
和"message"
。
有日志分析工具,但这是一个相当旧的系统,日志不是实时的,我正在分析和显示一些相当老的文件。
我不确定我是否真的理解你的规范,但下面的awk脚本可以作为一个起点:
$ cat foo.awk
BEGIN {
k[""key1""] = 1; k[""key7""] = 1; k[""key8""] = 1;
}
/"key1":"value1"/ {
s = "";
for(i = 1; i <= NF; i+=2)
if($i in k)
s = s (s ? "," : "") $i ":" $(i+1);
print s;
}
$ awk -F',|:' -f foo.awk foo.txt
"key1":"value1","key7":"value7","key8":"value8"
解释:
- awk被
-F',|:'
选项调用,这样每个记录中的字段分隔符是逗号或冒号。 - 在
BEGIN
部分,我们声明了一个关联数组(k
)的选择键,包括周围的双引号。 - awk脚本的其余部分应用于包含
"key1":"value1"
的每个记录。- 变量
s
用于准备输出字符串;初始化为""
。 - 对于每个奇数字段(键),我们检查它是否在
k
中。如果是,则连接到s
:- 如果
s
不为空,则使用逗号, - 关键字段,
- 一个冒号,
- 以下偶数字段(值)。
- 如果
- 我们打印
s
.
- 变量