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  bo.CommodityCerOrderBO - =====>属性订正任务执⾏开始|每页读取100条数据
2. 2011-08-23 19:57:05,012 [] INFO  bo.CommodityCerOrderBO - 当前正在处理页数:1
3. 2011-08-23 19:57:30,688 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:attr_ids不含0跳过
4. 2011-08-23 19:57:30,709 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性
id:100104
5. 2011-08-23 19:57:31,721 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性
id:100105
6. 2011-08-23 19:57:32,727 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性
id:100107
7. 2011-08-23 19:57:32,782 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:attr_ids成功保存为0|100104|0|100105|100107
8. 2011-08-23 19:57:32,782 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:attr_ids不含0跳过
9. 2011-08-23 19:57:32,805 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100104
10. 2011-08-23 19:57:33,828 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100107
11. 2011-08-23 19:57:33,838 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:46
12. 2011-08-23 19:57:34,850 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100106
13. 2011-08-23 19:57:35,860 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100105
14. 2011-08-23 19:57:36,871 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:3
15. 2011-08-23 19:57:36,884 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:3
16. 2011-08-23 19:57:36,891 [] INFO  bo.CommodityCerOrderBO - 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  bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:attr_ids不含0跳过
18. 2011-08-23 19:57:36,928 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:3
19. 2011-08-23 19:57:36,942 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100104
20. 2011-08-23 19:57:36,955 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100105
21. 2011-08-23 19:57:36,969 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100107
22. 2011-08-23 19:57:36,980 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:46
23. 2011-08-23 19:57:36,992 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第⼀个属
性id:100106
24. 2011-08-23 19:57:37,011 [] ERROR bo.CommodityCerOrderBO - 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  bo.CommodityCerOrderBO - =====>属性订正任务执⾏开始|每页读取100条数据
2011-08-23 19:57:05,012 [] INFO  bo.CommodityCerOrderBO - 当前正在处理页数:1
2011-08-23 19:57:30,688 [] INFO  bo.CommodityCerOrderBO - 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]][!] 指令 [参数]
忘记2011
» 地址的格式:⽤⾏号标识(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 bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100104
2011-08-23 19:57:31,721 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第⼀个属性id:100105
2011-08-23 19:57:32,727 [] ERROR bo.CommodityCerOrderBO - 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之