繁体   English   中英

使用 sed/awk 和正则表达式处理日志

[英]Using sed/awk and regex to process logs

我有 1000 个由非常冗长的 PHP 脚本生成的日志文件。 大体结构如下

###Unknown no of lines, which I want to ignore###
=================================================
$insert_vars['cdr_pkey']=17568
$id<TAB>$g1<TAB>$i1<tab>rating1<TAB>$g2<TAB>$i2<tab>rating2 #<TAB>more $gX,$iX,$ratingX
#numerical values of $id $g1 $i1 etc. separated by tab
#numerical values of ---""---
#I do not know how many lines will be there (unique column is $id)
=================================================
###Unknown no of lines, which I want to ignore###

我必须处理这些日志文件并创建一个 excel 表(我在想 csv 格式)并将数据报告回来。 我在 excel 方面真的很糟糕,但我想输出如下内容:

cdr_pkey<TAB>id<TAB>g1<TAB>i1<TAB>rating1<TAB>g2<TAB>rating2 #and so on
17568<TAB>1349<TAB>0.0004532<TAB>0.01320<TAB>2.014E-4<TAB>...#rest of numerical values
17568<TAB>1364<TAB>...#values for id=1364
17568<TAB>1321<TAB>...#values for id=1321
...
17569<TAB>1048<TAB>...#values for id=1048
17569<TAB>1426<TAB>...#values for id=1426
...
...

所以我的 cdr_pkey 是工作表中的唯一列,对于每个$cdr_pkey ,我有多个$id ,每个都有自己的一组$g1,$i1,$rating1...
测试该格式后,excel可以读取。 现在我只想将它扩展到所有这 1000 个文件。
我只是不确定如何进一步进行。 下一步是什么?

以下 bash 脚本执行的操作可能与您想要的有关。 当你说<TAB>时,它是由你的意思参数化的。 我假设您的意思是 ascii 制表符,但如果您的日志非常冗长以至于它们拼写出<TAB>您将需要相应地修改变量$WHAT_DID_YOU_MEAN_BY_TAB 请注意,这个脚本很少做 The Right Thing™; 它将整个文件读入一个字符串变量,这取决于你的日志文件有多大。 从好的方面来说,如果您认为这样更好,可以轻松修改脚本以进行两次传递。

#!/bin/bash

WHAT_DID_YOU_MEAN_BY_TAB='\t'

if [[ $# -ne 1 ]] ; then echo "Requires one argument: the file to process" ; exit 1 ; fi

FILENAME="$1"

RELEVANT=$(sed -n '/^==*$/,/^==*$/p' "$FILENAME" | sed '1d' | head -n '-1')
CDR_PKEY=$(echo "$RELEVANT" | \
    grep '$insert_vars\['"'cdr_pkey'\]" | \
    sed 's/.*=\(.*\)/\1/')
echo "$RELEVANT" | sed '1,2d' | \
    sed "s/.*/${CDR_PKEY}$WHAT_DID_YOU_MEAN_BY_TAB\0/"

以下find命令是一个示例使用,但您的情况将取决于您的日志的组织方式。

find. LOG_PATTERN -exec THIS_SCRIPT '{}' \;

最后,我忽略了将 CSV 标头放在 output 上的问题。 这很容易在带外完成。

(编辑:更新脚本以反映评论中的讨论。)

编辑:詹姆斯告诉我,将最后一个echo中的sed... 1d...更改为... 1,2...并删除grep -v 'id'应该可以解决问题。
确认它有效。 所以下面改一下。 再次感谢詹姆斯威尔科克斯。


基于@James 脚本,这就是我想出的。 我只是将最终的回声传送到grep -v 'id'
再次感谢詹姆斯威尔科克斯

WHAT_DID_YOU_MEAN_BY_TAB='\t' if [[ $# -lt 1 ]]; then echo "Requires at least one argument: the files to process"; exit 1; fi echo -e "key\tid\tg1\ti1\td1\tc1\tr1\tg2\ti2\td2\tc2\tr2\tg3\ti3\td3\tc3\tr3" for i in "$@" do FILENAME="$i" RELEVANT=$(sed -n '/^==*$/,/^==*$/p' "$FILENAME" | sed '1d' | head -n '-1') CDR_PKEY=$(echo "$RELEVANT" | \ grep '$insert_vars\['"'cdr_pkey'\]" | \ sed 's/.*=\(.*\)/\1/') echo "$RELEVANT" | sed '1, 2d' | \ sed "s/.*/${CDR_PKEY}$WHAT_DID_YOU_MEAN_BY_TAB\0/" #the one with grep looked like:- #echo "$RELEVANT" | sed '1d' | \ #sed "s/.*/${CDR_PKEY}$WHAT_DID_YOU_MEAN_BY_TAB\0/" | grep -v 'id' done

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM