我想从包含JSON sting的日志文件中解析数据,我想知道是否有一种方法让我使用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
?
我遇到了输出此命令任何部分输出的问题,这些输出允许我进行任何类型的字符串操作。
答案 0 :(得分:2)
使用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'