grep_1&2&3
什么是正则
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。
正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。
grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
正则就是一串又规律的字符串
掌握好正则对于编写shell脚本有很大帮助
各种编程语言中都有正则,原理是一样的
本章将要需欸写grep/egrep、sed、awk
grep
选项
grep [-cinvABC] 'word' filename
[root@zyshanlinux-01 grep]# grep 'nologin' passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin
-c或--count 行数
[root@zyshanlinux-01 grep]# grep -c 'nologin' passwd 16
-i或--ignore-case 不区分大小写,非常耗费时间尽量不用。
[root@zyshanlinux-01 grep]# grep -n 'nologin' passwd 3:daemon:x:2:2:daemon:/sbin:/sbin/nologin 4:adm:x:3:4:adm:/var/adm:/sbin/nologin [root@zyshanlinux-01 grep]# grep -in 'nologin' passwd 2:bin:x:1:1:bin:/bin:/sbin/Nologin 3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
-n或--line-number显示行号
[root@zyshanlinux-01 grep]# grep -n 'nologin' passwd 2:bin:x:1:1:bin:/bin:/sbin/nologin 3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
-v或--revert-match取反
[root@zyshanlinux-01 grep]# grep -ivn 'nologin' passwd 1:root:x:0:0:root:/root:/bin/bash 6:sync:x:5:0:sync:/sbin:/bin/sync
-r或--recursive遍历所有子目录
[root@zyshanlinux-01 ~]# grep -r 'root' /etc/ [root@zyshanlinux-01 ~]# grep 'root' /etc/ grep: /etc/: 是一个目录
-A后面跟数字,过滤处符合要求的行以及下面n行
[root@zyshanlinux-01 grep]# grep -nA2 'root' passwd 1:root:x:0:0:root:/root:/bin/bash 2-bin:x:1:1:bin:/bin:/sbin/Nologin 3-daemon:x:2:2:daemon:/sbin:/sbin/nologin -- 10:operator:x:11:0:operator:/root:/sbin/nologin 11-games:x:12:100:games:/usr/games:/sbin/nologin 12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
-B同上,过滤处符合要求的行以及上面n行
[root@zyshanlinux-01 grep]# grep -nB2 'root' passwd 1:root:x:0:0:root:/root:/bin/bash -- 8-halt:x:7:0:halt:/sbin:/sbin/halt 9-mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10:operator:x:11:0:operator:/root:/sbin/nologin
-C同上,同时过滤处符合要求的行以及上下各n行
[root@zyshanlinux-01 grep]# grep -nC2 'root' passwd 1:root:x:0:0:root:/root:/bin/bash 2-bin:x:1:1:bin:/bin:/sbin/Nologin 3-daemon:x:2:2:daemon:/sbin:/sbin/nologin -- 8-halt:x:7:0:halt:/sbin:/sbin/halt 9-mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10:operator:x:11:0:operator:/root:/sbin/nologin 11-games:x:12:100:games:/usr/games:/sbin/nologin 12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
注:grep仅仅是实现正则的工具而已,并不是正则。
正则表达式grep/egrep示例
[root@zyshanlinux-01 grep]# grep '[0-9]' passwd
[root@zyshanlinux-01 grep]# grep -v '[0-9]' passwd
[root@zyshanlinux-01 grep]# grep -nv '^#' inittab ##在[]外面的^代表以什么开头
[root@zyshanlinux-01 grep]# grep -nv '^[^0-9]' inittab ##在[]里面的^代表非,[^0-9]代表非数字
[root@zyshanlinux-01 grep]# grep 'r.o' passwd ##r.o这个点代表任意一个字符
[root@zyshanlinux-01 grep]# grep 'o*o' passwd ##星号代表重复前面一个字符0次或多次
[root@zyshanlinux-01 grep]# grep 'zyshan.*bash' passwd ##点星匹配所有字符,包括空行
[root@zyshanlinux-01 grep]# grep 'o\{2\}' passwd ##要脱义,花括号里面的数字代表重复前面的字符次数,花括号必须脱义,不脱义就不会匹配,仅代表一个花括号而已
[root@zyshanlinux-01 grep]# egrep 'o{2}' passwd ##egrep不用脱义
[root@zyshanlinux-01 grep]# grep -E 'o{2}' passwd ##加-E也不用脱义
[root@zyshanlinux-01 grep]# grep -E '(oo){2}' passwd ##用圆括号代表一个整体,相当于是四个0
[root@zyshanlinux-01 grep]# grep 'o\+o' passwd ##需脱义,加号代表重复前面的字符1次或多次,没0次
[root@zyshanlinux-01 grep]# grep 'o?t' passwd ##问号代表重复前面字符0次或1次
[root@zyshanlinux-01 grep]# grep -E 'root|nologin|997|Bus' passwd ##竖线代表或者
sed_4&5
sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
选项
-n或--quiet或——silent:仅显示script处理后的结果;
-e<script>或--expression=<script>:以选项中的指定的script来处理输入的文本文件;
参数
文件:指定待处理的文本文件列表。
sed命令
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
sed替换标记
g 表示行内全面替换。
p 表示打印行。
匹配
[root@zyshanlinux-01 sed]# sed -n '/root/'p test.txt
[root@zyshanlinux-01 sed]# sed -n '/r.t/'p test.txt ##点代表任意一个字符
[root@zyshanlinux-01 sed]# sed -n '/r*t/'p test.txt ##星重复前面一个字符0次或多次
[root@zyshanlinux-01 sed]# sed -nr '/o+t/'p test.txt ##加-r后加号不用加脱义号
[root@zyshanlinux-01 sed]# sed -nr '/o{2}/'p test.txt ##匹配两次o
[root@zyshanlinux-01 sed]# sed -nr '/root|bus/'p test.txt ##竖线代表或者
打印特定行
[root@zyshanlinux-01 sed]# sed -n '2'p test.txt ##打印前2行
[root@zyshanlinux-01 sed]# sed -n '2,5'p test.txt ##打印第2到第5行
[root@zyshanlinux-01 sed]# sed -n '25,$'p test.txt ##打印25行到末行
[root@zyshanlinux-01 sed]# sed -n '1,$'p test.txt ##打印全部
[root@zyshanlinux-01 sed]# sed -e '1'p -e '/bus/'p -n test.txt ##多重匹配
[root@zyshanlinux-01 sed]# sed -e '1'p -e '/root/'p -e '/oo*/'p -n test.txt ##可以继续写多个
[root@zyshanlinux-01 sed]# sed -n '/bus/'Ip test.txt ##加I选项可以不区分大小写匹配Bus;djisj2;434dbus❌81:81:System message bus:/:/sbin/nologin
[root@zyshanlinux-01 sed]# sed '1,25'd test.txt ##加d去掉前面25行后,打印剩下的行user5❌1010:1011::/home/user5:/bin/bashuser9❌1013:1013::/home/user9:/bin/bashuser19❌1014:1015::/home/user19:/bin/bashuser4❌1015:1016::/home/user4:/bin/bash[root@zyshanlinux-01 sed]# wc -l test.txt ##源文件没有改动,行数没变29 test.txt[root@zyshanlinux-01 sed]# sed -i '1,25'd test.txt ##加选项-i,删除前面25行[root@zyshanlinux-01 sed]# wc -l test.txt ##确认行数变少了4 test.txt
[root@zyshanlinux-01 sed]# sed -i '/user5/'d test.txt ##删除指定字符相关行
查找替换
[root@zyshanlinux-01 sed]# sed '1,10s/root/toor/g' test.txt ##s准备替换动作,在前10行把root替换成toor,g是全局替换
[root@zyshanlinux-01 sed]# sed '1,10s/ro+/r/g' test.txt |head ##在前10行把ro+替换成r,接的加号脱义
##前10行内容通过管道符过滤,想用圆括号需要在前面加-r或者脱义号,s前面不指定范围就指全部
[root@zyshanlinux-01 sed]# head test.txt |sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/'
##第一个([^:]+):代表冒号前非冒号的字符串,第二个(.*)贪婪匹配所有的字符,第三个:([^:]+)代表冒号后面的非冒号字符串,这三个用圆括号括起来是后面需要调用它,第一个圆括号用\1表示,第二个圆括号用\2表示,第三个圆括号用\3表示;目的是把第一个和第三个调换,所以要写成\3:\2:\1,///替换格式。
[root@zyshanlinux-01 sed]# head test.txt |sed -r 's/[a-zA-Z]//g' ##删除全部的字母,替换成空就好
##在文件内容每行前加上aaa:用圆括号加-r,用&代表圆括号部分,修改的内容放到&前面
[root@zyshanlinux-01 sed]# head test.txt |sed -r 's/(.*)/aaa:&/'aaa:root❌0:0:root:/root:/bin/bash
##在文件内容每行前加上bbb:用圆括号加-r,也可以用\1代表圆括号部分
[root@zyshanlinux-01 sed]# head test.txt |sed -r 's/(.*)/bbb:\1/'bbb:root❌0:0:root:/root:/bin/bash
sed 's/^.*$/123&/' test.txt ##与上面类似
awk工具_6&7
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
格式:awk 'BEGIN{} {} END{}' filename
awk语法结构: awk -F ':' 'BEGIN{语句} {if(条件){语句1;语句2;语句3} } END{语句}' filename
awk内置变量(预定义变量)
[A] OFS 输出字段分隔符(默认值是一个空格)。[A] NR 表示记录数,在执行过程中对应于当前的行号。[A] NF 表示字段数,在执行过程中对应于当前的字段数。
[root@zyshanlinux-01 awk]# awk -F ':' '{print $1,$2,$3}' test.txt ##打印每行的第一二三段
[root@zyshanlinux-01 awk]# awk -F ':' '{print $1"#"$2"#"$3}' test.txt ##字符#分割每段,字符带双引号
[root@zyshanlinux-01 awk]# awk -F ':' '{print $0}' test.txt ##打印全部
[root@zyshanlinux-01 awk]# awk '{print $0}' test.txt ##不指定分割符,默认从空格或空白开始
awk匹配
[root@zyshanlinux-01 awk]# awk '/oo/' test.txt
[root@zyshanlinux-01 awk]# awk -F ':' '$1 ~ /oo/' test.txt ##符号~代表匹配,$1代表第一段,匹配第1段带oo的
[root@zyshanlinux-01 awk]# awk -F ':' '$1 ~ /o+/' test.txt ##正则表达式
[root@zyshanlinux-01 awk]# awk -F ':' '$1 ~ /oo+/' test.txt
[root@zyshanlinux-01 awk]# awk -F ':' '/root/ {print $1,$3} /user/ {print $1,$3,$4}' test.txt ##多段表达式一起写,有root的打印第一三段,有user的打印第一三四段
awk数学运算表达式,运算符前后没有空格的
[root@zyshanlinux-01 awk]# awk -F ':' '$3==0' test.txt ##第3段等于0的,打印整行
[root@zyshanlinux-01 awk]# awk -F ':' '$3==0 {print $1}' test.txt ##第3段等于0的,打印第1行
[root@zyshanlinux-01 awk]# awk -F ':' '$3>=1000 {print $1}' test.txt ##第3段大于等于1000,打印第1行
[root@zyshanlinux-01 awk]# awk -F ':' '$3>=1000 {print $0}' test.txt ##1000如果针对数字不要加双引号
[root@zyshanlinux-01 awk]# awk -F ':' '$3>="1000" {print $0}' test.txt ##1000加双引号是按ASCII排序的,即是字符不是数字
[root@zyshanlinux-01 awk]# awk -F ':' '$3!="/sbin/nologin" {print $0}' test.txt ##不等于
[root@zyshanlinux-01 awk]# awk -F ':' '$3<$4' test.txt
[root@zyshanlinux-01 awk]# awk -F ':' '$3==$4' test.txt
[root@zyshanlinux-01 awk]# awk -F ':' '$3>"5" && $3<"7"' test.txt ##带双引号是字符比较
[root@zyshanlinux-01 awk]# awk -F ':' '$3>1000 || $7=="/sbin/nologin"' test.txt ##精准等于
[root@zyshanlinux-01 awk]# awk -F ':' '$3>1000 || $7 ~ /bash/' test.txt ##匹配
##OFS内置变量是用来指定print的分割符
[root@zyshanlinux-01 awk]# awk -F ':' '{OFS="#"} $3>1000 || $7 ~ /bash/ {print $1,$3,$7}' test.txt
[root@zyshanlinux-01 awk]# awk -F ':' '{OFS="#"} {print $1,$3,$7}' test.txt ##不指定条件就全部
[root@zyshanlinux-01 awk]# awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' test.txt ##加上修饰符if
##内置变量NR表示行、NF表示段,都是数字
[root@zyshanlinux-01 awk]# awk -F ':' '{print NR":"$0}' test.txt ##在每行开头打印行的记录数
[root@zyshanlinux-01 awk]# awk -F ':' '{print NF":"$0}' test.txt ##在每行开头打印每行的字段数
[root@zyshanlinux-01 awk]# awk -F ':' 'NR<=10' test.txt ##打印前10行,可以作为判断条件
[root@zyshanlinux-01 awk]# awk -F ':' 'NR<=10 && $1 ~ /root|sync/' test.txt ##两个条件一起用
[root@zyshanlinux-01 awk]# awk -F ':' 'NF==6 && $1 ~ /root|sync/' test.txt ##可以针对段进行操作
[root@zyshanlinux-01 awk]# awk -F ':' '{print $NR":"$NF}' test.txt ##对比带不带$的规律
[root@zyshanlinux-01 awk]# awk -F ':' '{print $NR":"$NF}' test.txt root:/bin/bash x:/sbin/nologin 2:/sbin/nologin 4:/sbin/nologin lp:/sbin/nologin /sbin:/bin/sync /sbin/shutdown:/sbin/shutdown :/sbin/halt [root@zyshanlinux-01 awk]# awk -F ':' '{print NR":"NF}' test.txt 1:7 2:7 3:7 4:7 5:7 6:7 7:7 8:7
[root@zyshanlinux-01 awk]# head -n 3 test.txt |awk -F ':' '$1="root"' ##一个等号赋值,分隔符没了 root x 0 0 root /root /bin/bash root x 1 1 bin /bin /sbin/nologin root x 2 2 daemon /sbin /sbin/nologin [root@zyshanlinux-01 awk]# head -n 3 test.txt |awk -F ':' '{OFS=":"} $1="root"' ##用变量分割恢复 root:x:0:0:root:/root:/bin/bash root:x:1:1:bin:/bin:/sbin/nologin root:x:2:2:daemon:/sbin:/sbin/nologin
[root@zyshanlinux-01 awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' test.txt ##求和,前面的大括号代表所有的组合,直接列出结果,内容由大括号代表了
[root@zyshanlinux-01 awk]# awk -F ':' '(tot=tot+$3); END {print tot}' test.txt ##求和缺少大括号,会把全部内容都列出来,最后是求和结果
[root@zyshanlinux-01 awk]# awk -F ':' '{tot=tot+$3} END {print tot}' test.txt ##简化
[root@zyshanlinux-01 awk]# awk -F ':' '{tot+=$3} END {print tot}' test.txt ##再简化
拓展:
正则表达式 http://www.apelearn.com/study_v2/chapter14.html
第十二课复习(以下为扩展学习内容)
打印某行到某行之间的内容http://ask.apelearn.com/question/559
sed转换大小写 http://ask.apelearn.com/question/7758
sed在某一行最后添加一个数字http://ask.apelearn.com/question/288
删除某行到最后一行 http://ask.apelearn.com/question/213
打印1到100行含某个字符串的行 http://ask.apelearn.com/question/1048
awk 中使用外部shell变量http://ask.apelearn.com/question/199
awk 合并一个文件 http://ask.apelearn.com/question/493
一个文件多行连接成一行 http://ask.apelearn.com/question/266
awk中gsub函数的使用 http://ask.apelearn.com/question/200
awk 截取指定多个域为一行 http://ask.apelearn.com/question/224
过滤两个或多个关键词 http://ask.apelearn.com/question/198
用awk生成以下结构文件 http://ask.apelearn.com/question/5494
awk用print打印单引号 http://ask.apelearn.com/question/1738
合并两个文件 http://ask.apelearn.com/question/945
awk的BEGIN和END http://blog.51cto.com/151wqooo/1309851
awk的参考教程 http://www.cnblogs.com/emanlee/p/3327576.html