参考:《Shell从入门到精通》
参考:几个常用的文本处理shell 命令:find、grep、sort、uniq、sed、awk
一、Shell文本处理
Linux中Shell命令可以完成简单的文本处理,也可以与正则表达式一起完成复杂的文本处理和批处理,常用的文本处理命令包括grep、sed、awk、sort和uniq,本文主要记录下这几个命令的相关用法(不断补充中)。
二、grep
grep 简单使用规则:
grep [选项]...模式 [文件]...@H_301_25@ (模式是正则表达式)
主要参数 []
- -c : 只输出匹配的行
- -I : 不区分大小写
- -h : 查询多文件时不显示文件名
- -l : 查询多文件时,只输出包含匹配字符的文件名
- -n : 显示匹配的行号及行
- -v : 显示不包含匹配文本的所有行(我经常用除去grep本身)
grep 'test' d* #显示所有以d开头的文件中包含test的行 grep 'test' aa bb cc #显示在 aa bb cc 文件中包含test的行 grep '[a-z]\{5}\' aa #显示所有包含字符串至少有5个连续小写字母的串 grep -c 'ERROR' demo.log #输出文件demo.log中查找所有包行ERROR的行的数量 grep -n '^a’ filename #-n 打印所过滤出行的行号 过滤以某字符为开头的行 grep -n '^[a-z]' filename #过滤以小写字母为开的行 grep '^$' filename #打印为空行的行号 grep -n '\.$' #打印以小数点为结尾的行 grep -v 'ERROR' demo.log #查找不含"ERROR"的行 grep -v '^$' filename #打印不为空的行 grep -v 'set' filename #打印文件中不包含set的行
三、sed
sed的基本使用规则:
sed [-nef] '[动作]' [输入文本]@H_301_25@
sed的模式有下列几种:
- -n : 安静模式@H_301_25@,一般sed用法中,来自stdin的数据一般会被列出到屏幕上,如果使用-n参数后,只有经过sed处理的那一行被列出来.
- -e : 多重编辑@H_301_25@,比如你同时又想删除某行,又想改变其他行,那么可以用 sed -e '1,5d' -e 's/abc/xxx/g' filename
- -f : 首先将 sed的动作写在一个档案@H_301_25@内,然后通过 sed -f scriptfile@H_301_25@ 就可以直接执行 scriptfile 内的sed动作@H_301_25@ (不推荐使用)
- -i : 直接编辑@H_301_25@,这回就是真的改变文件中的内容了,别的都只是改变显示. (不推荐使用)
- a 新增,a 后面可以接字符串@H_301_25@,而这个字符串会在新的一行出现. (下一行)
- c 取代,c 后面的字符串,这些字符串可以取代 n1,n2之间的行
- d 删除,后面不接任何东西@H_301_25@
- i 插入,后面的字符串,会在上一行@H_301_25@出现
- p 打印,将选择的资料列出,通常和 sed -n 一起运作 sed -n '3p' 只打印第3行
- s 取代,类似vi中的取代
- [line-address]q 退出,匹配到某行退出@H_301_25@,提高效率
- [line-address]r 匹配到的行读取某文件 例如: sed '1r qqq' abc,注意,写入的文本是写在了第1行的后边,也就是第2行
- [line-address]w file,匹配到的行写入某文件@H_301_25@ 例如: sed -n '/m/w qqq' abc,从abc中读取带m的行写到qqq文件中,这个写入带有覆盖性.
sed '1d' abc #删除 abc 档案里的第一行,这时会显示除了第一行之外的所有行,因为第一行已经被删除了(实际文件并没有被删除,而只是显示的时候被删除了) sed -n '1d' abc #什么内容也不显示,因为经过sed处理的行,是个删除操作,所以不显示. sed '2,$d' abc #删除abc中从第二行到最后一行所有的内容,$符号正则表达式中表示行末尾,但是这里并没有说那行末尾,就会指最后一行末尾,^开头,如果没有指定哪行开头,那么就是第一行开头 sed '$d' abc #只删除了最后一行,因为并没有指定是那行末尾,就认为是最后一行末尾 sed '/test/d' abc #文件中所有带 test 的行,全部删除 sed '/^$/d' abc #删除所有空行. sed '/test/a RR' abc #将RR 追加到所有的带 test 行的下一行 也有可能通过行 sed '1,5c RRRRRRR' abc sed '/test/c RR' abc #将RR 替换所有带 test 的行,当然,这里也可以是通过行来进行替换,比如 sed '1,5c RRRRRRR' abc sed 's/Windows/Linux/'abc #在每个输入行中,将第一个出现的"Windows"实例替换为"Linux". sed 's/BSOD/stability/g' abc #在每个输入行中,将所有"BSOD"都替换为"stability". sed 's/ *$//' abc #删除掉每行结尾的所有空格.
四、awk
awk的基本使用规则:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file@H_301_25@
awk的选项参数[-F|-f|-v]为:
- -F fs or --field-separator fs指定输入文件折分隔符,fs是一个字符串@H_301_25@或者是一个正则表达式@H_301_25@,如-F:。
- -v var=value or --asign var=value 赋值一个用户定义变量@H_301_25@。
- -f scripfile or --file scriptfile 从脚本文件中读取awk命令。
- BEGIN 初始化代码块@H_301_25@,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
- // 匹配代码块@H_301_25@,可以是字符串或正则表达式
- {} 命令代码块@H_301_25@,包含一条或多条命令
- ; 多条命令使用分号@H_301_25@分隔
- END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息@H_301_25@
以下是需要注意的要点:
- $0 表示整个当前行@H_301_25@
- $1 每行第一个字段
- NF 字段数量变量
- NR 每行的记录号,多文件记录递增
- FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
- \t 制表符
- \n 换行符
- FS BEGIN时定义分隔符
- RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
- ~ 匹配,与==相比不是精确比较
- !~ 不匹配,不精确比较
- == 等于,必须全部相等,精确比较
- != 不等于,精确比较
- && 逻辑与
- || 逻辑或
- + 匹配时表示1个或1个以上
- /[0-9][0-9]+/ 两个或两个以上数字
- /[0-9][0-9]*/ 一个或一个以上数字
- FILENAME 文件名
- OFS 输出字段分隔符, 默认也是空格,可以改为制表符等
- ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
- -F'[:#/]' 定义三个分隔符
基本的工作方式如下所示:
awk '{print $0}' log.log #查找出日志文件中的每一列 awk '{print %$1 "\t"$7}' log.log #查找出文件中的第一列和第七列 cat file | awk '$0 !~ /192.168.10.2/' | grep 'PHP' |wc -| #匹配192.168.10.2的ip地址统计。!~为不匹配 awk 'BEGIN{print "header1","header2"} {print $1,$2} END{print "bottom1","bottom2"}' test #格式化test中的前两列并添加头和底部输出 awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test #查找空行
五、sort
sort的基本规则如下所示:
sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+<起始栏位>-<结束栏位>][--help][--verison][文件]@H_301_25@
sort的选项参数如下:
- -b 忽略每行前面开始出的空格字符。
- -c 检查文件是否已经按照顺序排序。
- -d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。
- -f 排序时,将小写字母视为大写字母。
- -i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。
- -m 将几个排序好的文件进行合并。
- -M 将前面3个字母依照月份的缩写进行排序。
- -n 依照数值的大小排序。
- -o <输出文件> 将排序后的结果存入指定的文件。
- -r 以相反的顺序来排序。
- -t <分隔字符> 指定排序时所用的栏位分隔字符。
- + <起始栏位>-<结束栏位> 以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
- -- help 显示帮助。
- -- version 显示版本信息。
基本的工作方式如下所示:
sort -d /etc/passwd #按照字典顺序排序 sed -f test.sed demolog.log | sort -t@ -k2,2n -k3,3r -k1,1 #-t表示用@作为分割符,-k表示用分割出来的第几个域排序,n为按数字排序,r为倒序 # 2011-08-23 19:57:30@10117@INFO@status:attr_ids message1 # 2011-08-23 19:57:32@10117@INFO@status:attr_ids message2
六、uniq
uniq命令用于去重,其基本规则如下所示:
uniq的选项参数如下所示:
- -c 显示输出中,在每行行首加上本行在文件中出现的次数@H_301_25@。它可取代- u和- d选项。
- -d 只显示重复行。
- -u 只显示文件中不重复的各行。
- -n 前n个字段与每个字段前的空白一起被忽略。一个字段是一个非空格、非制表符的字符串,彼此由制表符和空格隔开(字段从0开始编号)。
- +n 前n个字符被忽略,之前的字符被跳过(字符从0开始编号)。
- -f n 与- n相同,这里n是字段数。
- -s n 与+n相同,这里n是字符数。
基本的工作方式如下所示:
awk '{print $1}' /var/log/httpd/access_log | sort | uniq -c #把apache网站的所有访问ip统计出来,并打印统计次数 cat test |sort | uniq -c #显示排序后文件中每行连续出现的次数。 uniq -f 2 -s 2 test #忽略每行的前2个字段,忽略第二个空白字符和第三个字段的首字符