通过外部 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'
我想从包含 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'