首页 > 解决方案 > 以比 grep-while-prinf 更简单、更优雅的方式从使用 reges 处理的日志文件中提取值

问题描述

我有几个看起来像这样的日志文件:

#LOGa# 180.149.126.169 ## 85 with value 350.00000000000000000000 due brand: 350.00000000000000000000 country: 0 {2020-11-26_11-01-00}
#DETAILS_hits# 180.149.126.169 ## hits=([brand/17]="1" [brand/18]="1" [no_brand]="1" ) {2020-11-26_11-01-00}
#LOG_brand# 180.149.126.169 ## BRANDS=([anyBrand]="1" ) {2020-11-26_11-01-00}
#LOG_country# 180.149.126.169 ## COUNTRY=([anyCountry/17]="1" [anyContinent/18]="1" ) {2020-11-26_11-01-00}

我想提取一些特定日志行的圆顶值

我当然可以去

grep -HiRE "(#LOGa#)(.+)(## )(.+)" --include \myFile.log | while read _ ip _ rank _ value _ _ valueBrand _ _ valueCountry _ ; do printf "%.0f %.0f\n" $valueBrand $valueCountry; done

但不是一种更优雅的方式,比如

cleanME myFile.log "(#LOGa#)($ip)(## )($rank)(with value)($value)(due brand:)($valueBrand)(country:)($valueCountry)(.*)" "$valueBrand.0f $valueCountry.0f"

当然我可以去构建一个这样的函数,但我不记得它比 grep + while + printf 更好的方法

标签: bashgrepprintf

解决方案


如果Perl碰巧是您的选择,请尝试:

perl -ne '/^#LOGa#\s+([\d.]+)\s+##\s+([\d.]+)\s+with value\s+([\d.]+)\s+due brand:\s+([\d.]+)\s+country:\s+([\d.]+)/ && printf "%.0f %.0f\n", $4, $5' myFile.log

提供的输入的输出:

350 0
  • 该选项-n告诉Perl将输入文件逐行处理为sed.
  • 该选项-e启用单线。
  • /regex/ && printf ...只有当该行与正则表达式匹配时,语法才会打印参数grep
  • 正则表达式中的括号创建捕获组,匹配的子字符串可以按顺序用$1, , ... 引用。$2

推荐阅读