【问题标题】:Parse JQ output through external bash function?通过外部bash函数解析JQ输出?
【发布时间】:2018-03-07 00:53:49
【问题描述】:

我想从包含 JSON 字符串的日志文件中解析出数据,我想知道是否有办法让我使用 bash 函数来执行任何自定义解析,而不是重载 jq 命令。

命令:

tail errors.log --follow | jq --raw-output '. | [.server_name, .server_port, .request_file] | @tsv' 

输出:

8.8.8.8     80     /var/www/domain.com/www/public

我想解析第 3 列以剪切字符串以排除 /var/www/domain.com 部分,其中 /var/www/domain.com 是文档根,/var/www/domain.com/subdomain/public 是网站的公共 html 部分。因此,我想将我的输出保留为/subdomain/public(或来自示例/www/public)。

我想知道我是否可以以某种方式注入 bash 函数来解析 .request_file 列?或者我将如何使用jq 来做到这一点?

我在输出此命令的任何部分的输出时遇到问题,我可以执行任何类型的字符串操作。

【问题讨论】:

  • 只有domain.com,或者你想修剪前三个目录,不管它们是什么?结果第三列应该是www/public 还是/www/public?我在回答中做了一些假设,但更好的问题将提供 desired 输出的明确示例,而不仅仅是当前输出。
  • /www/public 将是所需的输出。
  • 顺便说一句,选项(如--follow)应始终位于参数之前(如errors.log); GNU 工具允许它反过来,但POSIX utility syntax guidelines 明确表示只保证支持选项优先排序。
  • 嗯。这可能会令人困惑,因此如果源是 www.example.com,则期望输出是 /subdomain/public,即 /www/domain.com。
  • 请edit该问题包含一个明确的反例(包括当前输出和所需输出),您担心现有答案可能无法按预期运行。

标签: bash parsing logging jq tail


【解决方案1】:

使用BashFAQ #1 while read 循环遍历行,并使用BashFAQ #100 parameter expansion 执行所需的修改:

tail -f -- errors.log \
  | jq --raw-output --unbuffered \
       '[.server_name, .server_port, .request_file] | @tsv' \
  | while IFS=$'\t' read -r server_name server_port request_file; do
      printf '%s\t%s\t%s\n' "$server_name" "$server_port" "/${request_file#/var/www/*/}"
    done

注意--unbuffered 的使用,强制jq 立即刷新其输出行,而不是缓冲它们。这会降低性能(因此不是默认设置),但它可以确保您在从可能很慢的输入源读取数据时立即获得输出。


也就是说,删除jq 中的前缀也很容易,所以没有特别的理由这样做:

tail -f -- errors.log | jq -r '
  def withoutPrefix: sub("^([/][^/]+){3}"; "");
  [.server_name, .server_port, (.request_file | withoutPrefix)] | @tsv'

【讨论】:

  • 我喜欢第一个选项,但是当我理解它们时,它们都会非常有用。请帮我调试第一个示例。当我运行第一个命令时,日志刷新时我没有得到任何输出。也许这让我更了解我的上一个问题,无法从尾巴中抽出任何东西?
  • 第二个选项确实有效,但只删除了 /var/。不用担心细节,我知道了。
  • 抓住了——这就是缓冲。如果你有足够的内容,它最终会被刷新。见BashFAQ #9。如果您要从 jq 管道到控制台以外的其他设备,则需要使用 --unbuffered 标志。
  • Re:第二个选项,{3} 告诉它要删除多少块。我在发布之前对其进行了测试,它删除了指示的数字,因此我需要查看您如何实施/测试的详细信息以说明任何失败。
  • 有效!你是我的野兽。真的很感激。
猜你喜欢
  • 2020-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 2023-04-08
相关资源
最近更新 更多