linux - 设置捕获组的长度

标签 linux bash

我想格式化我的服务器日志,以便在执行“tail -f”时易于阅读。

我的日志看起来像:

{"item1":"ab","item2":"cdef","item3":"ghi"}
{"item1":"abc","item2":"defgh","item3":"i"}

我想获得:

var1=ab__  | var2=cdef_ | var3=ghi
var1=abc_  | var2=defgh | var3=i__

其中 '_' 是一个空格。

现在我使用:

 sed -E 's/.*item1":"(.*)","item2":"(.*)","item3":"(.*)".*/var1=\1 | var2=\2 | var3=\3/'

然后我得到:

var1=ab | var2=cdef | var3=ghi
var1=abc | var2=defgh | var3=i

可以设置捕获组\1\2\3 的长度吗?用空格填充它们还是截断它们?

我想固定每个字段的长度(填充或截断)并实时流式传输我的日志。

最佳答案

评论已经在推荐jq

这是一种方法:

$ jq -r '[(.item1, .item2, .item3)] | @tsv' log.json
ab      cdef    ghi
abc     defgh   i

请注意,@tsv 过滤器是在 jq 1.5 版中引入的,因此如果您使用的是 1.4,也许是时候升级了。 :)

如果你想要垂直条,你可以在数组中添加它们:

$ jq -r '[(.item1, "|", .item2, "|", .item3)] | @tsv' log.json
ab      |       cdef    |       ghi
abc     |       defgh   |       i

请注意,@tsv 在每个字段之间添加了一个制表符,因此这可能不是您想要的。但是,它可以很容易地被 bash 解析:

$ while IFS=$'\t' read one two three; do \
  printf 'var1=%-4s  | var2=%-5s | var3=%-4s\n' "$one" "$two" "$three"; \
  done < <(jq -r '[(.item1, .item2, .item3)] | @tsv' log.json)
var1=ab    | var2=cdef  | var3=ghi
var1=abc   | var2=defgh | var3=i

或者,如果特定格式不重要,而您只是想让事情排成一行,也许是这样:

$ jq -r '[(.item1, "|", .item2, "|", .item3)] | @tsv' log.json | column -t
ab   |  cdef   |  ghi
abc  |  defgh  |  i

当然,这不处理tail -f,它只是涉及格式化。如果您希望能够处理一个,您可能需要在循环中执行此操作。例如:

tail -F "$logfile" | while read -r line; do
  jq -r '[(.item1, .item2, .item3)] | @tsv' <<< "$line" |
  while IFS=$'\t' read one two three; do
    printf 'var1=%-4s  | var2=%-5s | var3=%-4s\n' "$one" "$two" "$three"
  done
done

请注意,此处选择的格式化选项是 printf,因为所有其他解决方案都需要了解输入数据的最大长度。对于 printf,我们假设您已经知道最大长度,并已在您的格式字符串中考虑到它。

关于linux - 设置捕获组的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48100013/

相关文章:

bash - 如何在 Bash 中读取文件或标准输入

bash - 使用git时如何查找所有空文件夹和未跟踪文件?

c - 在用户写入的同时写入输出

Android 手机默认 Shell

linux - Grive 文件同步、压缩和密码保护

python - cd 到目录的 Bash 脚本?

Linux Bash Number Range echo 语法错误

bash - 如何使用循环保存所有 key 保管库 secret

linux - 获取 C++ 代码的 x86 指令大小?

linux - 在 Linux 中对多个文件执行命令