公司做统计提取字段的服务是C编译出的bin文件,经常core dump导致机器挂断,深受其苦,自己写了一个shell版的作为替代。
本来打算用awk实现,
awk -F "[= ]" ‘{do something}’
这样,可是日志字段不固定(可能出现,可能不出现),不太好实现,就该用grep了,每两个字段出现的前后顺序倒是固定的。
脚本如下(get_fields.sh):
#! /bin/bash
#set -x
# the default delimiter
fs=" "
ret=""
# get options
while getopts F:k: opt
do
case "$opt" in
F)
fs=$OPTARG;;
k)
keys=$OPTARG;;
esac
done
# split string into an array
keys=(${keys//,/ })
num=${#keys[@]}
if [ $num -eq 0 ];
then
echo "not enough parameter";
exit;
fi
while read line
do
retstr=""
found=0
for key in ${keys[@]}
do
# \bxxx : word start by xxx
tmpstr=`echo ${line} | grep -oE "\b${key}=[^${fs}]*" `
# do only when string is not empty
[ -n "${tmpstr}" ] && retstr=${retstr}${tmpstr}${fs} && let found+=1
done
# check num
[ -n "${retstr}" -a $found -eq $num ] && echo -e ${retstr}"\n" | sed '/^$/d'
done
使用实例:
test.log:
a=1 b=2 c=3 d=a
要提取出a,c两个字段:
cat test.log | sh get_fields.sh -F " " -k a,c
结果:
a=1 c=3
最后,感谢亚杰对getopts的技术支持!感谢正则三十分钟入门教程!
------------
更新:
在ChinaUnix上发了贴,问了这个问题,大牛们的回答太给力了!!!
地址:http://bbs.chinaunix.net/thread-4169843-1-1.html
最终,我还是采用了awk:
cat test.log | grep -E "\bname" | awk '{for(i=1;i<=NF;i++)s=($i~/^name=|^Pc=/)?s"\t"$i:s;$0=s;s=""}NF+=0'