首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从大日志文件中提取数据的bash脚本

从大日志文件中提取数据的bash脚本
EN

Stack Overflow用户
提问于 2020-05-20 01:40:12
回答 5查看 1.2K关注 0票数 0

我使用的是FreeBSD (on Citrix NetScaler)…我面临的挑战是从一个日志中提取Mbps,这个日志实际上有100行行。

日志如下所示,其中带有十进制的Mbps数可以从0.0到9999.99或更多。也就是说。

代码语言:javascript
复制
#>alphatext_anylength... (more_alphatext_in brackets)... Mbps (1.0)… alphatext_anylength... (more_alphatext_in brackets)... 
#>alphatext_anylength... (more_alphatext_in brackets)... Mbps (500.15)… alphatext_anylength... (more_alphatext_in brackets)... 
#>alphatext_anylength... (more_alphatext_in brackets)... Mbps (1500.01)… alphatext_anylength... (more_alphatext_in brackets)... 

现在的挑战是,我想用小数过滤掉所有Mbps的括号内的数字,即A)大于500 Mbps的行号。也就是说,对于上面的示例输出,我只想看到以下内容:

代码语言:javascript
复制
#>[line number 20] 500.15
#>[line number 55] 1500.01

我试过:

代码语言:javascript
复制
cat output.log | sed -n -e 's/^.*Mbps//p' |cut -c 3-10

这让我在Mbps之后有10个字符。但这还不够聪明,不能只显示大于500 this的括号内的十进制数。

我很感激这可能是个挑战。不过,如果有任何能创造魔法的bash脚本向导,我会很感激的!

提前感谢!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2020-05-20 02:01:09

您可以使用awk来匹配包含Mbps (的行,这些行后面是任何非)字符,后面是)。然后将字符串的开头替换为Mbps (,将字符串的开头替换为空字符串,并将)到末尾的字符串替换为空字符串。

如果转换为数字(+0)的其余行大于500,则打印行号和行。

代码语言:javascript
复制
awk '
  /Mbps \([^)]*\)/{ sub(/.*Mbps \(/, ""); sub(/\).*/, "") }
  ($0+0) > 500{ print FNR, $0 }
' file

编辑:匹配值> 50的Mbps后包含可选空格的行,请使用

代码语言:javascript
复制
awk '
  /Mbps ?\([^)]*\)/{ sub(/.*Mbps ?\(/, ""); sub(/\).*/, "") }
  ($0+0) > 50{ print FNR, $0 }
' file
票数 0
EN

Stack Overflow用户

发布于 2020-05-20 03:22:24

代码语言:javascript
复制
$ awk '{match($0,/Mbps \(([^)]*)\)/,a);if(a[1] > 500){print NR,a[1]} }' ./infile
2 500.15
3 1500.01
票数 1
EN

Stack Overflow用户

发布于 2020-05-20 08:07:59

使用三轮sed (用GNU sed测试,不确定它是否在BSD sed上工作),主要说明为什么sed不是这项工作最简单的工具:

代码语言:javascript
复制
sed '=;s/.*).*(\([0-9.]*\)).*(.*/ \1/' output.log | 
sed ':a;s/[0-9]*/#>[line number &]/;N;s/\n//g;n;ba' | 
sed -n '/\b\([5-9]\|[0-9]\{2,\}\)[0-9]\{2,\}[^]]/p'

或者在不理解sed的BSD sed上,尝试(尝试,因为我没有运行BSD):

代码语言:javascript
复制
sed '=;s/.*).*(\([0-9.]*\)).*(.*/ \1/' output.log | 
sed ':a;s/[0-9]*/#>[line number &]/;N;s/
//g;n;ba' | 
sed -n '/\b\([5-9]\|[0-9]\{2,\}\)[0-9]\{2,\}[^]]/p'

输出:

代码语言:javascript
复制
#>[line number 2] 500.15
#>[line number 3] 1500.01

注:为什么是三轮?

sed.

  • That
  1. =输出当前行号,但输出绕过任何行缓冲区,使行号在对=的单个调用中不可见,也会输出不需要的\n,而在sed中,这是不方便的。参见works.
  2. sed代码如何只看到字符串的,它不知道数字,也不知道如何根据值找到数字范围。关于我们如何伪装它,请参见。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61903702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档