前言
对于测试中出现的log,我们经常需要提取其中的关键信息进行分析,之前我通常使用python的工具来处理一些字符串,但是效率不是很高。现在通过shell脚本的方法会极大的增加效率,一句话就可以在任意的txt文本中提取到我们想要的字段,下面我们来看一下这个神奇的工具。
0. 一个例子
假如我们要从下面这段txt格式的log中提取‘sequence’后面的数据以及‘alpha’后面的数据,我们仅通过一句怎么来实现这个功能呢?
02-11 10:30:56.062 1512 1512 D OplusLayer: setAlpha sequence=6092, alpha=1.000000, name=Surface(name=5213b6f InputMethod)/@0x45bb15a - animation-leash of insets_animation#0
02-11 10:30:56.062 1512 1512 D OplusLayer: setAlpha sequence=6145, alpha=4.000000, name=Surface(name=5213b6f InputMethod)/@0x45bb15a - animation-leash of insets_animation#0
02-11 10:30:56.062 4132 4363 D OplusFastRecovery: network netid not match!! null,103
02-11 10:30:56.063 1512 1512 D OplusMovieIdle: updateLayerStacks,mOmiSupport is not supoort
我们只需要以下命令就可以得到我们想要的数据:
cat old.log | grep "setAlpha" | awk -F: '{ print $4}' | awk -F, '{ print $1"="$2 }' | awk -F= '{ print $2 "," $4 }'> new.log
这句命令乍一看比较复杂,但是实际上逻辑很简单,我们来一步步解析这条指令是怎么实现的。
1. cat命令
cat old.log
cat命令是常用的shell命令,此处的作用就是打开文件名为“old.log”的文件,并准备进行编辑。这个文件也可以是‘.txt’格式结尾的。
2. '|'符号与‘>’符号
shell命令中,‘|’符号表示的是管道。假设输入了如下指令:command0 | command1,则command0的输出流入到command1中。在我们的指令中,‘|’负责把上一句执行的输出当作输入流入到下一句。
‘>’符号在本文指令中的作用是重定向到文本, cat指令将文本打开,然后通过’|‘符号流入到后续的语句进行处理,处理完之后通过’>'将处理之后的结果存放在指定文本中。
3. grep命令
grep指令常用于搜索文本文件中是否含有某些特定模式的字符串。该命令以行为单位读取文本并使用正则表达式进行匹配,匹配成功后打印出该行文本。
grep命令记住两点,第一,它用来匹配文本中的字符串,第二,以行为单位读取,也就是说,如果文本中国一行含有目标字符串,grep就将整行打印出来。我们指令中的grep用法为:
grep "setAlpha"
我们在终端输入命令(需要将终端定位到文件路径下):
cat old.log | grep "setAlpha"
运行结果为:
可以看到,这句命令将含有“setAlpha”字符串的语句成行地打印了出来,对于log中比较多地数据,我们可以将结果保存在新的文件中:
cat old.log | grep "setAlpha" > new.log
运行完毕之后,会出现一个‘new.log’文件,打开我们就可以看到和之前终端显示一样的内容:
4. awk命令
AWK 是一种处理文本文件的语言,处理文本非常方便,熟悉python的同学可以把它当作python中的split()函数,它的作用就是根据指定字符来对文本进行分割并生成列表。
举个例子:
cat old.log | grep "setAlpha" | awk -F: '{ print $4}'
这句话的意思就是,awk语句根据前面生成的文本,以‘-F’后面的符号,即‘:’(冒号)为分界点进行分割,然后将分割后的第四个元素打印出来(即‘print $4’),运行结果为:
这样我们可以初步提取到包含我们想要信息的数据,后面可以根据该输出进一步处理文本:
cat old.log | grep "setAlpha" | awk -F: '{ print $4}' | awk -F, '{ print $1"="$2 }'
上面语句的含义就是将文本以‘,’(逗号)为分界点就行分割,并且打印第1个和第2个元素,两个元素中间用‘=’符号连接。运行结果为:
现在的结果越来越接近我们想要的了,然后我们根据这一结果进一步处理:
cat old.log | grep "setAlpha" | awk -F: '{ print $4}' | awk -F, '{ print $1"="$2 }' | awk -F= '{ print $2 "," $4 }'
我们根据上一步的结果以‘=’为分界点进行分割,然后打印第2个与第4个元素,两个元素之间用“,”连接,运行结果为:
可以看到通过我们之前一系列步骤的处理,我们想要的数据已经呈现出来了,对于数据量比较大的文本,我们可以将最终的结果存储到一个文件中:
cat old.log | grep "setAlpha" | awk -F: '{ print $4}' | awk -F, '{ print $1"="$2 }' | awk -F= '{ print $2 "," $4 }' > new.log
我们打开new.log文件发现我们的结果已经在里面了:
掌握这个命令的逻辑之后,我们就可以从海量的数据中批量提取具有一定规则的字段。