设定捕获组的长度

时间:2018-01-04 16:54:49

标签: 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的长度吗?用空格填充或截断它们?

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

3 个答案:

答案 0 :(得分:1)

评论已经在推荐jq

这是一种方法:

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

请注意@tsv过滤器是在jq 1.5版本中引入的,所以如果您使用的是1.4,那么可能需要升级。:)< / SUP>

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

$ 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,我们假设您已经知道最大长度,并在格式字符串中对其进行了解释。

答案 1 :(得分:0)

jq + printf 解决方案:

jq -rs '.[] |
@sh "printf \"var1=%-8s| var2=%-8s| var3=%-8s\n\" \(.item1) \(.item2) \(.item3)"' log | sh

输出:

var1=ab      | var2=cdef    | var3=ghi     
var1=abc     | var2=defgh   | var3=i  
  • -s - 不是为输入中的每个 JSON 对象运行过滤器,而是将整个输入流读入一个大型数组并仅运行一次过滤器
  • @sh - 输入转义适合在 POSIX shell的命令行中使用

https://stedolan.github.io/jq/manual/v1.5/

答案 2 :(得分:0)

将您的sed输出传输到column -t以制作表格。