我有一个非常详细的PHP脚本生成的1000个日志文件。一般结构如下
###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
s,每个$g1,$i1,$rating1...
都有自己的一组{{1}}
在测试这种格式后,excel可以读取。现在我只想将它扩展到所有这1000个文件
我只是不确定如何继续前进。下一步是什么?
答案 0 :(得分:3)
以下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标头放在输出上的问题。这很容易在带外完成。
(编辑:更新了脚本以反映评论中的讨论。)
答案 1 :(得分:1)
编辑:詹姆斯告诉我,将sed
中的echo
从... 1d ...
更改为... 1,2 ...
并删除grep -v 'id'
应该可以解决问题。
确认它有效。所以在下面改变它。再次感谢James Wilcox
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