通过外部 bash 函数解析 JQ 输出?

Parse JQ output through external bash function?

我想从包含 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 是 public html 网站部分。因此,我想将我的输出保留为 /subdomain/public(或示例 /www/public)。

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

我在输出此命令的任何部分的输出时遇到问题,这将允许我进行任何类型的字符串操作。

使用 BashFAQ #1 while read loop to iterate over the lines, and a 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 立即刷新其输出行而不是缓冲它们。这会降低性能(因此它不是默认值),但它确保您在从 potentially-slow 输入源读取时立即获得输出。


也就是说,删除 jq 中的前缀也很容易,因此没有特别的理由执行上述操作:

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