编程工具四Shell文本处理

参考:《Shell从入门到精通

参考:几个常用的文本处理shell 命令:find、grep、sort、uniq、sed、awk

一、Shell文本处理

Linux中Shell命令可以完成简单的文本处理,也可以与正则表达式一起完成复杂的文本处理和批处理,常用的文本处理命令包括grep、sed、awk、sort和uniq,本文主要记录下这几个命令的相关用法(不断补充中)。

二、grep

grep 简单使用规则:

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] '[动作]' [输入文本]

sed的模式有下列几种:

  • -n : 安静模式,一般sed用法中,来自stdin的数据一般会被列出到屏幕上,如果使用-n参数后,只有经过sed处理的那一行被列出来.
  • -e : 多重编辑,比如你同时又想删除某行,又想改变其他行,那么可以用 sed -e '1,5d' -e 's/abc/xxx/g' filename
  • -f : 首先将 sed的动作写在一个档案内,然后通过 sed -f scriptfile 就可以直接执行 scriptfile 内的sed动作 (不推荐使用)
  • -i : 直接编辑,这回就是真的改变文件中的内容了,别的都只是改变显示. (不推荐使用)
动作:
  • a 新增,a 后面可以接字符串,而这个字符串会在新的一行出现. (下一行)
  • c 取代,c 后面的字符串,这些字符串可以取代 n1,n2之间的
  • d 删除,后面不接任何东西
  • i 插入,后面的字符串,会在上一行出现
  • p 打印,将选择的资料列出,通常和 sed -n 一起运作 sed -n '3p' 只打印第3行
  • s 取代,类似vi中的取代
  • [line-address]q 退出,匹配到某行退出,提高效率
  • [line-address]r 匹配到的行读取某文件 例如: sed '1r qqq' abc,注意,写入的文本是写在了第1行的后边,也就是第2行
  • [line-address]w file,匹配到的行写入某文件 例如: 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

awk的选项参数[-F|-f|-v]为:

  • -F fs or --field-separator fs指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:
  • -v var=value or --asign var=value 赋值一个用户定义变量
  • -f scripfile or --file scriptfile 从脚本文件中读取awk命令。
  • BEGIN 初始化代码,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
  • // 匹配代码,可以是字符串或正则表达式
  • {} 命令代码,包含一条或多条命令
  • 多条命令使用分号分隔
  • END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

以下是需要注意的要点:

  • $0 表示整个当前行
  • $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][文件]

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 [选项] 文件

uniq的选项参数如下所示:

  • -c 显示输出中,在每行行首加上本行在文件中出现的次数。它可取代- 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个字段,忽略第二个空白字符和第三个字段的首字符

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...