shell字符串的处理(截取,连接,匹配,替换,翻转)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

shell字符串的处理(截取,连接,匹配,替换,翻转)shell 字符串的处理(截取,连接,匹配,替换,翻转)
本节分享下,字符串处理的内容,包括:截取,连接,匹配,替换,翻转等。

1,字符串的截取
⽅法⼀:
代码⽰例:
echo $a|awk ’{print substr( ,1,8)}’
substr是awk中的⼀个⼦函数,对第⼀个参数的进⾏截取,从第⼀个字符开始,共截取8个字符,如果不够就从第⼆个字符中补充
⽅法⼆
代码⽰例:
echo $a|cut -b2-8
cut:对标准输⼊的字符串进⾏处理
cut -bn-m:以byte为单位,从第n个byte开始,取m个
cut -bn,m:以byte为单位,截取第n,m个byte
cut -b-n,m:以byte为单位,截取1-n,和第m个
-c:以charactor为单位
-d:指定分隔符,默认为tab
-s:使标准输⼊中没有delimeter
cut -f1:截取第1个域
⽅法三
a=123456
echo $
⽅法四
使⽤sed截取字符串的最后两位
代码⽰例:
echo $test |sed ’s//(.*/)/(../)$//’
截取字符串的前2位
代码⽰例:
echo $test |sed ’s/^/(../)/(.*/)//’
2,字符串的⽐较
好像没有什么可以⽐较的
3,字符串的连接
$a$b
或者
$string
4,字符串的翻转
⽅法⼀:
使⽤rev
⽅法⼆:
编写脚本实现
代码⽰例:
#!/usr/bin/awk -f
{
revline = ""
for (i=1;i<=length;i++)
{
revline = substr(,i,1) revline
}
}
END{print revline}
5,字符串的匹配
grep
egrep
fgrep
6,字符串的排序
sort
7,字符串的替换
bash中:
代码⽰例:
%x=ababcd
%echo $ # 只替换⼀个
bbcdabcd
%echo $ # 替换所有
bbcdbbcd
sh中:
如何替换/
使⽤sed
替换所有匹配
代码⽰例:
echo $test |sed ’s/xx/yy’
替换单个匹配
8,得到字符串的长度:
bash当中
$
或者
expr "$VAR" : ’.*’
9,判断字符串是否为数字
10,得到字符串中某个字符的重复次数
代码⽰例:
echo $a |tr "x" "/n" | -l
得到的结果需要减去1
或者
代码⽰例:
echo $a |awk -F"x" ’{print NF-1}’
11,得到字符串中某个string的重复次数
12,将⼀批⽂件中的所有string替换
代码⽰例:
for i in file_list
do
vi $i <<-!
:g/xxxx/s//XXXX/g
:wq
!
done
13,如何将字符串内每两个字符中间插⼊⼀个字符
使⽤
代码⽰例:
echo $test |sed ’s/../&[insert char]/g’
======================================================================================================================================
概述
我们⽇常应⽤中都离不开⽇志。

可以说⽇志是我们在排查问题的⼀个重要依据。

但是⽇志并不是写了就好了,当你想查看⽇志的时候,你会发现线上⽇志堆积的长度已经超越了你⼀⾏⾏浏览的耐性的极限了。

于是,很有必要通过⼀些⼿段来⾼效地辅助你来快速的从⽇志中找到你要找的问题。

本⽂通过⼀个从项⽬中衍⽣出来的例⼦从查找⽇志,筛选⽇志和统计⽇志3个⽅⾯层层递进来简述⽇志⽂件查看中⼀些有⽤的⼿段。

(注:在linux环境下)
⽬录
例⼦背景:
后台跑⼀个定时任务,对指定时间段的订单数据表中的每⼀条记录进⾏以此任务处理。

在⽇志中输出:
1.订单id
2.订单处理状态
3.⽇志类别
准备⼯具:sort, tail, less, uniqu,grep,sed,awk
⽰例⽇志:demo.log
[plain]
1. 2011-08-23 19:57:00,610 [] INFO modityCerOrderBO - =====>属性订正任务执⾏开始|每页读取100条数据
2. 2011-08-23 19:57:05,012 [] INFO modityCerOrderBO - 当前正在处理页数:1
3. 2011-08-23 19:57:30,688 [] INFO modityCerOrderBO - order-fix.curr_id:10117,status:attr_ids不含0跳过
4. 2011-08-23 19:57:30,709 [] ERROR modityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性
id:100104
5. 2011-08-23 19:57:31,721 [] ERROR modityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性
id:100105
6. 2011-08-23 19:57:32,727 [] ERROR modityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性
id:100107
7. 2011-08-23 19:57:32,782 [] INFO modityCerOrderBO - order-fix.curr_id:10117,status:attr_ids成功保存为0|100104|0|100105|100107
8. 2011-08-23 19:57:32,782 [] INFO modityCerOrderBO - order-fix.curr_id:10226,status:attr_ids不含0跳过
9. 2011-08-23 19:57:32,805 [] ERROR modityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100104
10. 2011-08-23 19:57:33,828 [] ERROR modityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100107
11. 2011-08-23 19:57:33,838 [] ERROR modityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:46
12. 2011-08-23 19:57:34,850 [] ERROR modityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100106
13. 2011-08-23 19:57:35,860 [] ERROR modityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100105
14. 2011-08-23 19:57:36,871 [] ERROR modityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:3
15. 2011-08-23 19:57:36,884 [] ERROR modityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:3
16. 2011-08-23 19:57:36,891 [] INFO modityCerOrderBO - order-fix.curr_id:10226,status:attr_ids成功保存为6|100104|0|0|100107|46|100106|100105|3|3
17. 2011-08-23 19:57:36,891 [] INFO modityCerOrderBO - order-fix.curr_id:10222,status:attr_ids不含0跳过
18. 2011-08-23 19:57:36,928 [] ERROR modityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:3
19. 2011-08-23 19:57:36,942 [] ERROR modityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100104
20. 2011-08-23 19:57:36,955 [] ERROR modityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100105
21. 2011-08-23 19:57:36,969 [] ERROR modityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100107
22. 2011-08-23 19:57:36,980 [] ERROR modityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:46
23. 2011-08-23 19:57:36,992 [] ERROR modityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100106
24. 2011-08-23 19:57:37,011 [] ERROR modityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:3
0.⼀些最基础的⽇志查看命令
最简单的⽇志查看命令就是浏览⽇志⽂件了,⼀般会从有限浏览⽂件末尾的
[plain]
1. tail -400f demo.log #监控最后400⾏⽇志⽂件的变化等价与 tail -n 400 -f (-f参数是实时)
2. less demo.log #查看⽇志⽂件,⽀持上下滚屏,查找功能
3. uniq -c demo.log #标记该⾏重复的数量,不重复值为1
以上命令具体使⽤详见本机man⼿册
1.查找关键⽇志记录 grep
浏览了⽇志⽂件后你会发现,⽇志⽂件成千上万⾏,怎么能找到我要找的内容呢。

这时候,就可已⽤grep来进⾏⽇志的关键⾏提取了。

grep 简单使⽤
规则:grep [选项]...模式 [⽂件]... (模式是正则表达式)
例⼦1:
[plain]
1. grep 'INFO' demo.log #在⽂件demo.log中查找所有包⾏INFO的⾏
输出:
2011-08-23 19:57:00,610 [] INFO modityCerOrderBO - =====>属性订正任务执⾏开始|每页读取100条数据
2011-08-23 19:57:05,012 [] INFO modityCerOrderBO - 当前正在处理页数:1
2011-08-23 19:57:30,688 [] INFO modityCerOrderBO - order-fix.curr_id:10117,status:attr_ids不含0跳过
...(略)
例⼦2:
[plain]
1. grep -o 'order-fix.curr_id:[0−9]\+' demo.log #-o选项只提取order-fix.curr_id:xxx的内容(⽽不是⼀整⾏),并输出到屏幕上
输出:
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10226
...(略)
例⼦3:
[plain]
1. grep -c 'ERROR' demo.log #输出⽂件demo.log中查找所有包⾏ERROR的⾏的数量
输出:17
例⼦4:
[plain]
1. grep -v 'ERROR' demo.log #查找不含"ERROR"的⾏
输出:(功能和grep 'INFO' demo.log 命令⼀样,输出略)
grep ⽤法⼩结(转⾃⽹络图⽚):请点击直接查看
详细⽤法请man之
2.精简⽇志内容 sed
从n多⾏的⽇志⽂件中提取到⼀定数量的⾏后,可能你还会觉得有些功能不够,⽐如你每⾏并不需要有哪个类抛出的描述,⽐如你不需要⽇志时间,或者要把时间格式换个形式展⽰等等,这时候你就可以通过sed的替换命令来进⾏对⽇志⽂件提取具体内容了。

如果把grep⽐作过滤器,那sed就是个修改器了。

sed简单⽤法:
[plain]
1. sed [-n][-e] '命令' ⽂件 #-n选项是默认不输出信息,除⾮使⽤了p命令或者是s命令的p标志符;-e是表明空格后⾯接的是⼀个命令
2. sed [-n] -f 脚本⽂件 #这个⽤法是把命令写在脚本⾥
»'命令'的格式: [地址1[,地址2]][!] 指令 [参数]
» 地址的格式:⽤⾏号标识(1 表明匹配第⼀⾏),或者⽤正则表达式匹配('^INFO'表明该地址匹配以INFO打头的⾏)
» 指令的例⼦:p打印指令,s替换指令,d删除指令等等(以下表格摘⾃abs的sed⼩册⼦):
操作符名字效果
[地址范围]/p打印打印[指定的地址范围]
[地址范围]/d删除删除[指定的地址范围]
s/pattern1/pattern2/替换将指定⾏中, 将第⼀个匹配到的pattern1, 替换为pattern2.
操作符名字效果
[地址范围]/s/pattern1/pattern2/替换在地址范围指定的每⼀⾏中, 将第⼀个匹配到的pattern1, 替换为pattern2.
[地址范围]/y/pattern1/pattern2/transform在地址范围指定的每⼀⾏中, 将pattern1中的每个匹配到pattern2的字符都使⽤pattern2的相应字符作替换. (等价于tr命令)
g, 将模式匹配都作相应的操作. (译者注: 不只局限于第⼀个匹配)
⼩结:sed就是遍历对于输⼊⽂件的每⼀⾏,如果该⾏匹配地址1,地址2的范围之内,那么就对这⼀⾏执⾏命令。

例1:(摘⾃abs的sed⼩册⼦)
8d删除输⼊的第8⾏.
/^$/d删除所有空⾏.
1,/^$/d从输⼊的开头⼀直删除到第1个空⾏(第⼀个空⾏也删除掉).
/Jones/p只打印那些包含"Jones"的⾏(使⽤-n选项).
s/Windows/Linux/在每个输⼊⾏中, 将第⼀个出现的"Windows"实例替换为"Linux".
s/BSOD/stability/g在每个输⼊⾏中, 将所有"BSOD"都替换为"stability".
s/ *$//删除掉每⾏结尾的所有空格.
s/00*/0/g将所有连续出现的0都压缩成单个的0.
/GUI/d删除掉所有包含"GUI"的⾏.
s/GUI//g将所有"GUI"都删除掉, 并保持剩余部分的完整性.
看完基本⽤法,让我们结合demo.log来具体应⽤下:
例2:输出demo.log中的某个⽇期中的ERROR的⾏
来具体应⽤下:
[plain]
1. sed -n '/^2011-08-23.*ERROR/p' demolog.log
输出:
2011-08-23 19:57:30,709 [] ERROR modityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100104
2011-08-23 19:57:31,721 [] ERROR modityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100105
2011-08-23 19:57:32,727 [] ERROR modityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100107
例3:提取demo.log中的⽇期,⽇志级别,订单id和状态。

[plain]
1. sed -f demo.sed2 demo.log
[plain]
1. #n #这⼀⾏⽤法和命令中的-n⼀样意思,就是默认不输出
2. #demo.sed2
3.
4. #下⾯的⼀⾏是替换指令,就是把19位长的⽇期和INFO/ERROR,id,和后⾯的⼀截提取出来,然后⽤@分割符把这4个字段重新按顺序组合
5. s/^[−0−9]{19}.*INFO∥ERROR .*order-fix.curr_id:[0−9]\+,.∗$/\1@\3@\2@\4/p
输出:
2011-08-23 19:57:30@10117@INFO@status:attr_ids不含0跳过
2011-08-23 19:57:30@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100104
2011-08-23 19:57:31@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100105
2011-08-23 19:57:32@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100107
2011-08-23 19:57:32@10117@INFO@status:attr_ids成功保存为0|100104|0|100105|100107
...略
sed详细⽤法可以参考《sed 与 awk》(第⼆版), 或者man之
3.对记录进⾏排序 sort
经过了⽇志⽂件的精炼后,我们可能不想对⽇志进⾏时间排序,这时候我们就可以⽤sort进⾏排序。

基本使⽤
sort [options] [file...]
对于demo.log,经过了上⾯的sed提取后,我希望先⽤id进⾏排序,然后再⽤⽇志级别倒序进⾏排序,最后才是⽇期排序
[plain]
1. #排序功能 -t表⽰⽤@作为分割符,-k表⽰⽤分割出来的第⼏个域排序(不要漏掉后⾯的,2/,3/,1,详细意思看下⾯的参考链接,这⾥不做详述)
2. sed -f test.sed demolog.log | sort -t@ -k2,2n -k3,3r -k1,1 #n为按数字排序,r为倒序
输出:
2011-08-23 19:57:30@10117@INFO@status:attr_ids不含0跳过
2011-08-23 19:57:32@10117@INFO@status:attr_ids成功保存为0|100104|0|100105|100107
2011-08-23 19:57:30@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100104
2011-08-23 19:57:31@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100105
2011-08-23 19:57:32@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100107
2011-08-23 19:57:36@10222@INFO@status:attr_ids不含0跳过
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100104
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100105
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100106
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100107
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:3
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:46
2011-08-23 19:57:37@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:3
2011-08-23 19:57:32@10226@INFO@status:attr_ids不含0跳过
2011-08-23 19:57:36@10226@INFO@status:attr_ids成功保存为6|100104|0|0|100107|46|100106|100105|3|3
2011-08-23 19:57:32@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100104
2011-08-23 19:57:33@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100107
2011-08-23 19:57:33@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:46
2011-08-23 19:57:34@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100106
2011-08-23 19:57:35@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100105
2011-08-23 19:57:36@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:3
2011-08-23 19:57:36@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:3
4.统计⽇志相关记录数 awk
现在⽇志已经⽐较清晰了,但是如果我想对不同⽇志进⾏统计怎么办,⽐如我要统计所有ERROR的⽇志记录书,或者要统计每个订单有多少个ERROR?这就需要我们的awk 帮忙了。

awk简单使⽤:
[plain]
1. awk [-v 变量名=变量值] [-Fre] [--] '模式 { 语句 }' 变量名=变量值⽂件名
2. awk [-v 变量名=变量值] [-Fre] -f 脚本⽂件 [--] 变量名=变量值⽂件名
和sed⼀样,awk也⽀持2中⽅式调⽤,⼀种是把awk脚本直接在命令⾏写⼊,第⼆种是把awk写在⽂件中在命令⾏中调⽤。

awk处理⽅式也与sed类似,对⽂件中的每⼀个输⼊⾏进⾏处理,每个处理⾸先判断是否是模式中匹配的⾏,是的话就具体执⾏相应的语句。

不同的是,awk侧重与对每⼀⾏的列进⾏处理,并且,awk脚本和c语⾔类似也拥有变量,条件判断,循环等复杂语句,所以这⾥只能简单介绍⼀下基本应⽤,详细的请查看后⾯给出的相关链接。

⽽且,awk在处理所有⾏前和处理完⾏后各有BEGIN和END语句做预处理和后置处理。

例⼦1:打印⽇志中的第2,3列
[plain]
1. awk 'BEGIN{FS="@"} {print $2,$3}' demo.log_after_sort #BEGIN中预处理的是,把@号作为⾏的列分割符,把分割后的⾏的第2,3列输出
输出:(对于从sort得出的结果作为输⼊)
10117 INFO
10117 ERROR
10117 ERROR
10117 ERROR
10222 INFO
...略
例⼦2. 统计⽇志中INFO,ERROR出现的总数,以及总记录数
[plain]
1. #下⾯的例⼦是作为命令⾏输⼊的,利⽤单引号作为换⾏标记,这样就不⽤另外把脚本写进⽂件调⽤了
2. awk '
3. BEGIN {
4. FS="@"
5. }
6.
7. {
8. if ($3 == "INFO") {info_count++}
9. if ($3 == "ERROR") {error_count++}
10.
11. }
12.
13. END {
14. print "order total count:"NR #NR是awk内置变量,是遍历的当前⾏号,到了END区域⾃然⾏号就等于总数了
15. printf("INFO count:%d ERROR count:%d\n",info_count,error_count)
16. } ' demo.log_after_sort
输出:
order total count:22
INFO count:5 ERROR count:17
例⼦3. 对指定时间范围内的⽇志进⾏统计,包括输出INFO,ERROR总数,记录总数,每个订单记录分类统计
下⾯的例⼦综合了前⾯sed和sort
[plain]
1. sed -f demo.sed demolog.log | sort -t@ -k2,2n -k3,3r -k1,1 | awk -f demo.awk
[plain]
1. #demo.awk
2. BEGIN {
3. FS="@"
4. stime="2011-08-23 19:57:31"
5. etime="2011-08-23 19:57:37"
6. }
7.
8. $1 > stime && $1 < etime {
9. if ($3 == "INFO") {info_count++}
10. if ($3 == "ERROR") {error_count++}
11.
12. ++total
13.
14. status[$2]=status[$2]"\t"$1"\t"$3"\t"$4"\n"
15.
16. }
17.
18. END {
19. for(i in status){
20. printf("id:%s:\n%s\n",i,status[i])
21. }
22.
23. print "order total count:"total
24. printf("INFO count:%d ERROR count:%d\n",info_count,error_count)
25. } <span style="font-size:18px;"><strong>
26. </strong></span>
输出:
2011-08-23 19:57:32 INFO status:attr_ids成功保存为0|100104|0|100105|100107
2011-08-23 19:57:32 ERROR status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100107 id:10226:
2011-08-23 19:57:32 INFO status:attr_ids不含0跳过
2011-08-23 19:57:32 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100104 2011-08-23 19:57:33 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100107 2011-08-23 19:57:33 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:46 2011-08-23 19:57:34 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100106 2011-08-23 19:57:35 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属性id:100105
#这个例⼦只是举例说明awk的统计⽤法,实际运⽤中可能会统计超时的次数,页⾯访问次数等。

awk相关资料:
《sed 与 awk》(第⼆版)
补充:
其他实践时例⼦:
1. 在本地分⽀把代码修改从⼀个分⽀复制到另⼀个分⽀(例⼦的b1022st.txt是⼀个记录了⽂件新增或修改的变化的⽂件路径名)
[plain]
1. awk 'BEGIN{FS="b1022-scm/"} {system("cp -rf b1022-scm/"$2" b1022-lpscm/"$2);}' /home/nizen/b1022st.txt
通过awk和其system命令结合,这样就把⽂件从b1022-scm复制到b1022-lpscm下
[java]
1. BEGIN {
2. running=0
3. count=0
4. startRow="begin =====>" id #id,nextId是通过-v 参数从外部传⼊
5. endRow="begin =====>" nextId
6. }
7.
8. $0 ~ startRow{ # ~是匹配运算符,判断$0是否满⾜startRow正则表达式
9. running = 1
10. # printf("start\n")
11. }
12.
13. $0 ~ endRow {
14. running = 0
15. # printf("end\n")
16. }
17.
18. {
19. if(running==1) { # 仅在startRow 和 endRow 范围内统计
20. if($0 ~ "it show") {
21. # printf($0 "\n")
22. str=$0
23. sub(/^.*show times:/, "", str)
24. sub(/ .*$/, "", str)
25. printf(str "\n")
26. count = count + str
27. }
28. }
29. }
30.
31. END {
32. printf("showTimeCount:"+count)
33. }
6. printf "10ms occur:%.2lf%%\n",t10/total*100 #输出百分⽐数据,精确到百分位后2位
5.⽇志规范化
从前⾯可以看出,⽇志⽂件为了要让后续⼯具能够对⾥⾯的内容进⾏提取和处理,就必须要让⽇志⽂件规范的输出。

个⼈想到有⼏个点可以规范:
1.记录⽇志时候可以写⼊⼀些特殊的⽂本语句,⼀遍与⼯具的检索和处理。

2.记录⽇志最好不要⽤中⽂,因为在不同语⾔环境下对⽇志的处理可能因为编码不同导致没法处理⽇志。

后⾯再贴下淘宝中找到的⼀些打印⽇志的建议:
正常情况下应该返回true, 却返回false的, 反正就是你在对返回值进⾏检查的时候, 如果不正常, log⼀下
出现异常的地⽅, 以前认为hsf.log会帮我们记下所有的异常, 但是这个也不⼀定可靠, 所以还得我们⾃⼰记⼀下
⽇志必须包含上下⽂信息
如果出于统计的需要, 可打可不打
在完成代码之后, 查看⼀下整个代码结构, 在⼀些关键的点, 加上⽇志, 正常的info, 少数情况出现的warning, 异常情况的error或者warning
打印的⽇志内容要容易查询, 以前我⽐较倾向于打中⽂⽇志, 虽然易读, 但是中⽂在linux下的搜索统计稍微有些⿇烦,所以如果能加上英⽂标识(⽐如说⽤于唯⼀标识的前缀),能识别不同⽇志, 这个对定位也是⾮常有好处的.
6.⼀些容易遇到的问题
a.处理中⽂出现乱码
这个主要是因为你的linux locale的配置,与编辑⽂件的语⾔环境,还有你登录ssh客户端的编码规则有关,所以最好还是不⽤中⽂记录⽇志。

b.正则表达式不同⼯具的区别
这个主要是因为不同⼯具的正则表达式定义的元字符不同,⽹上有总结的,可点击参考
OO后记:
⽬前只是简单介绍了grep,sed,sort,awk的⼏个简单应⽤,实际上的⽇志监控回根据不同的情景进⾏不同的处理。

⽐如需要对调⽤的耗时进⾏统计(平均时间或者超时记录),对访问量进⾏统计,但是基本原理都和本⽂例⼦出发点⼀致。

本⽂⼀⽅⾯是为了记录下学习过程中积累的东西,另⼀⽅⾯为了抛砖引⽟引起⼤家对⽇志记录的关注。

=========================================================================================================================================。

相关文档
最新文档