使用正则表达式使用sed解析一行

时间:2016-01-29 00:48:13

标签: sed

使用2016-01-29T00:38:43.662697+00:00 heroku[worker.2]: source=worker.2 dyno=heroku.17664470.d3f28df1-e15f-3452-1234-5fd0e244d46f sample#memory_total=54.01MB sample#memory_rss=54.01MB sample#memory_cache=0.00MB sample#memory_swap=0.00MB sample#memory_pgpgin=17492pages sample#memory_pgpgout=3666pages我想解析Heroku的日志运行时指标,如下所示:

worker.2: 54.01MB

所需的输出是:

sed -E 's/.+source=(.+) .+memory_total=(.+) .+/\1: \2/g' (54.01MB为memory_total)

我无法管理,虽然我尝试了几种选择,包括:

{{1}}

我的命令出了什么问题?如何纠正?

2 个答案:

答案 0 :(得分:2)

.+source=之后的memory_total=都是贪婪的,所以他们尽可能多地接受这一行。使用[^ ]表示“除空格之外的任何内容”,以便它知道停止的位置。

sed -E 's/.+source=([^ ]+) .+memory_total=([^ ]+) .+/\1: \2/g'

将您的内容放入https://regex101.com/会让您的内容变得非常明显。

答案 1 :(得分:1)

我会选择老式的,可靠的,非扩展的sed表达式,并确保模式不是太贪婪:

sed -e 's/.*source=\([^ ]*\) .*memory_total=\([^ ]*\) .*/\1: \2/'

-e -E相反,后者主要是Mac OS X(BSD)sed选项; GNU sed的正常选项是-r-e只是意味着下一个参数是脚本中的表达式。

这将从给定的数据行生成所需的输出:

worker.2: 54.01MB
  

奖金问题:流中有一些奇怪的行,我通常可以使用像| grep memory_total这样的grep管道将它们过滤掉。但是,如果我尝试将其与sed命令一起使用,则它不起作用。没有产生输出:

 heroku logs -t -s heroku | grep memory_total | sed.......

有时grep | sed是必要的,但它通常是多余的(除非您使用的grep功能不受sed支持,例如Perl正则表达式)

你应该可以使用:

sed -n -e '/memory_total=/ s/.*source=\([^ ]*\) .*memory_total=\([^ ]*\) .*/\1: \2/p'

-n表示默认不打印"。 /memory_total=/匹配您之后的行; s///内容与之前相同。我删除了以前的g后缀;无论如何,正则表达式永远不会匹配多次。我添加p以在替换发生时打印该行。