我有一个包含以下内容的日志文件。
2021-06-15T22:50:11+00:00 DEBUG {"slug": "something", "key2": "value2"}
我想要tail -f
这个文件并将结果通过管道传递给命令,但我需要在管道传递之前jq
删除部分,因为需要一个 JSON 字符串。2021-06-15T22:50:11+00:00 DEBUG
jq
jq
有没有办法同时尾部日志文件并删除日期时间部分?
最终,我想使用以下命令。
tail -f :file | jq
答案1
假设您可以访问sed
能够执行无缓冲输出的 GNU:
tail -f file | sed -u 's/^[^{]*//' | jq .
这将tail -f
在您的文件上运行并不断将新数据发送到sed
.该sed
命令会将所有内容删除到行中第一个之前的空格{
,然后将结果发送到jq
。
-u
GNU 的选项使其sed
不缓冲输出。如果没有此选项,sed
将缓冲结果,并且仅在jq
缓冲区(4 Kb?)已满时才发送数据。当工具的输出不是终端本身时,进行这样的缓冲是标准过程,并且这样做是出于效率原因。在这种情况下,我们可能想关闭缓冲,因此我们使用-u
.
仅选择DEBUG
JSON 数据之前包含字符串的行:
tail -f file | sed -u -e '/^[^{]*DEBUG /!d' -e 's///' | jq .
或者
tail -f file | sed -u -n 's/^[^{]*DEBUG //p' | jq .
这里的命令sed
将删除所有不以不包含{
字符的文本开头、以 结尾的行DEBUG
。如果找到这样的行,则会删除匹配的文本,留下 JSON 数据。
请注意,我们在这里基于字符串DEBUG
而不是{
初始化 JSON 对象来提取 JSON。
与管道中的缓冲相关:
答案2
要删除前 2 个空格分隔的列:
tail -f file | stdbuf -oL cut -d ' ' -f3- | jq .
(stdbuf -oL
如 GNU 或 FreeBSD 系统上所见,cut
进行基于行而不是基于块的输出缓冲的技巧)。