我有一个包含以下内容的日志文件。
2021-06-15T22:50:11+00:00 DEBUG {"slug": "something", "key2": "value2"}
Run Code Online (Sandbox Code Playgroud)
我想要tail -f
这个文件并将结果通过管道传递给jq
命令,但我需要2021-06-15T22:50:11+00:00 DEBUG
在管道之前剥离部分,jq
因为jq
需要一个 JSON 字符串。
有没有办法拖尾日志文件并同时去除日期时间部分?
最后,我想使用以下命令。
tail -f :file | jq
Run Code Online (Sandbox Code Playgroud)
假设您可以访问sed
能够进行无缓冲输出的GNU :
tail -f file | sed -u 's/^[^{]*//' | jq .
Run Code Online (Sandbox Code Playgroud)
这将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 .
Run Code Online (Sandbox Code Playgroud)
或者
tail -f file | sed -u -n 's/^[^{]*DEBUG //p' | jq .
Run Code Online (Sandbox Code Playgroud)
sed
此处的命令将删除所有不以某些不包含{
字符的文本开头的行,以DEBUG
. 如果找到这样的行,则删除匹配的文本,留下 JSON 数据。
请注意,我们在这里根据DEBUG
字符串而不是{
启动 JSON 对象的 JSON 提取JSON。
与管道中的缓冲相关:
要删除前 2 个空格分隔的列:
tail -f file | stdbuf -oL cut -d ' ' -f3- | jq .
Run Code Online (Sandbox Code Playgroud)
( stdbuf -oL
,如在 GNU 或 FreeBSD 系统上发现的那样,使用cut
基于行而不是基于块的输出缓冲的技巧)。