awk-grep-sed简单使用总结(正则表达式的应用)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

正则表达式:

匹配一组字符:
#[ns]a.\.xls  //[]用于限定字符;“.”用于匹配任意字符; \.用于转义"."
匹配到s/na*.xls 
[nN]     匹配大小写;[0-9]     匹配0-9数字;[a-zA-Z0-9]   匹配任意字符数字
注意:"-"(连字符)是一个特殊的元字符,作为元字符只能用在[]中间
        用^元字符进行取非操作,但是必须用在[]之间
#[ns]a[^0-9]\.xls 匹配n/sa*.xls    *表示任意字符

使用元字符:
元字符自己使用必须进行转义,"["也是一个元字符,表示字符集合的开始
#array\[[0-9]\]   匹配一个数组,显示下表
匹配各种空白字符的元字符;
linux下#\n\n用来匹配空白行(windows下使用\r\n\r\n 回车和换行)
#\d  匹配任意一个数字字符(等价于[0-9])
#\D  匹配任意一个非数字字符(等价于[^0-9])
#array\[\d\]   仍然可以匹配一个数组
注意:正则表达式一般大小写是相反的意思
#\w 匹配任何一个字母数字字符(大小写均可以)或下划线(等价于[a-zA-Z0-9_])
#\W 匹配任何一个非字母数字或非下划线字符(等价[^a-zA-Z0-9_])
#\s 匹配任何一个空白字符(等价于[\f\n\t\r\v])
#\S 任何一个非空字符(等价[^\f\n\t\r\v])


重复匹配:
注意:@字符不需要转义;
        想要匹配同一个字符的多次重复,只需要简单的加上+字符作为后缀。[0-9]+  表示多个数字重复 ‘+’也是一个元字符
#[\w.]+@[\w.]+\.\w+  匹配一个完整的邮件地址
注意:当在字符集合里使用的时候,像".""+"等字符被解释为普通字符,不需要转义。不过转义也可以。
         想要匹配零个或者多个字符可以使用*
#\w+[\w.]*@[\w.]+\.\w+  完整的邮箱地址(因为第一个字符不能为.啊)
"+"和"."的区别:前者是至少匹配一次,后者是至少匹配零次(*也是一个元字符)
         想要匹配0个或者一个字符可以使用?
#http?://[\w.]+  //匹配一个完整的域名(https)

匹配的重复次数:(一般使用{}括写来进行定义)
注意:{和}是元字符,如果需要匹配{}本身需要进行转义。(\{3\}表示前一个字符出现了三次)
#\d{1,2}[-\/]\d{1,2}[-\/]\d{2,4}  //匹配日期(月/日/年或日-月-年)
\d表示匹配数字,{1,2}表示匹配1-2次;[-\/]表示匹配-或者/
 注意;?等价于{0,1}
匹配至少重复多少次:
#\d+:  \$\d{3,}\.\d{2}                             //匹配单号和单价($---.--)
\d+:匹配单号:    \$匹配美元符号$   \d{3,}匹配数字至少三个  \.匹配小数点

防止过度匹配:
#<[Bb]>.* //这样子会匹配第一个和最后一个之间的所有
原因:因为*和+都是贪婪型字符,可以在之后加?就可以变成懒惰型
#<[Bb]>.*? //这样就会匹配每一个之间的字符了

 

位置匹配:
使用边界限定符:
#\bcat\b  //限定cat的两边,因此固定查找cat
(空格是用来分隔单词的字符之一)
\b是这样一个位置:位于一个能够用来构成单词的字符(与\w可以匹配的字符)和一个不能用来构成单词的字符(\W)之间
\B不匹配一个单词边界
#\B-\B  //匹配-
字符串边界:(用来定义字符串边界的元字符有两个:^定义字符串开头;$用来定义字符串结尾)
注意:^只有用在[]中才是求非运算。
#^\s*<\?xml.*\?>   //匹配字符。
注意:^\s*将匹配一个字符串的开头位置和随后的零个或多个空白字符;还将注意的是.*是贪婪型的,如果xml文档结构比较完全就需要使用.*?懒惰型了
#\s*$  //匹配一个字符串结尾的零个或者多个空白字符

分行匹配模式:
启用分行匹配模式的(?m)记号就是一个能够改变其他元字符行为的元字符序列。
分行匹配模式将使得正则表达式引擎把分隔符当做一个字符串分隔符来对待。在分行模式匹配下,^不仅匹配正常的字符串开头,还将匹配行分隔符(换行符)后面的开始位置;类似地,$不仅匹配正常的字符串结尾,还将匹配行分隔符(换行符)后面的匹配模式
#(?m)^\s*//.*$  //匹配每行以//开头
^\s*//.*$将匹配任何以//开头的若干字符,最后以$结尾
加上(?m)后,整个正则表达式将换行符视为一个字符串分隔符,这样就可以把每一行//打印

 


使用子表达式:
子表达式必须用()括起来.注意()也是元字符,因此需要匹配本身的时候也需要进行转义。
#(\d{1,3}.){3}\d{1,3} //匹配IP地址
注意:这样匹配是回存在一些不合法的IP的。
#(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))
#(19|20)\d{2}  //匹配以19或20开头的四位数


回朔引用:前后一致匹配
回朔引用就是让前后匹配查找。
#<[hH][1-6]>.*? 匹配标题部分,但是有可能匹配到


回朔引用可以避免前后不一致
回朔引用允许正则表达式模式引用前面的匹配结果。
#[ ]+(\w+)[ ]+\1 //匹配空格若干字符加空格若干  \1表示引用(\w+)内容
类似于sed
 #echo $hello | sed 's/\(......\)\(.*\)\(...\)$/\1\3/'
\1 表示匹配模式里的第一个子表达式

#<[hH]([1-6])>.*? //\1匹配前面查找到的([1-6])
注意:回朔引用只能用来引用模式里的子表达式(())括起来的正则表达式片段
子表达式是通过他们的相对位置来引用的:\n表示匹配第n个位置的变量


前后查找:
向前查找:就是一个以?=开头的子表达式,需要匹配的文本跟在=后面
注意:前后查找有一个"消费"的概念"匹配和返回文本"。在向前查找中,被匹配的文本不包含在最终返回的匹配没结果中,成为'不消费'
#.+(?=:)  //向前查找,表示遇到:就停止查找,且不输出:(过滤协议)
这个就是"不消费",只匹配不显示
#.+(:)   //向前查找,可以消费后面:
注意:在使用向前查找的时候,正则表达式分析器将向前查找并处理:匹配,但不会把它包括在最终的搜索结果里。

向后查找:查找出现先在被匹配文本之前的字符(但不消费它),向后查找符?<=
#\$[0-9.]+  //匹配美元价格
#(?<=\$)[0-9.]+  //匹配$之后的数字

把向前查找和向后查找结合起来;
#(?<=<[Hh][tT][Mm][Ll]>).*(?=)   //查找标签之内的内容

对前后查找取非:
正向前查找,正向后查找:
(?=) //正向前查找
(?<=) //证向后查找
(?!) //反向前查找
(?

#(?<=\$)\d+  查找文本中的没有价格(只显示$后的数字)
#\b(?


嵌入条件:
#\(?\d{3}\)?-?\d(3)-\d{4}  0或(开头连续3个数字,0或一个),0或一个- 连续3个数字,-连续四个数字
(102) -345-7890

正则表达式里的条件:其实是需要使用?进行定义的。
#?匹配前一个字符或者表达式
#?=和?<=匹配前面或者后面的文本。
回朔引用条件只在前面的子表达式搜索取得成功的情况下才允许使用一个表达式。

#(\()?\d{3}(?(1)\)|-)\d{3}-\d{4}
(?(1)\)|-)是一个回朔条件,它根据条件是否得到满足而去匹配")"或-
 #(\()?应该是匹配前括号"("的吧
整体效果就是前三位数字如果没有括号就显示:123-245-9800  如果有括号就显示;(123)456-9980

前后查找条件:
#\d{5}(-\d{4})?   \d{5}匹配前5个数字,(-\d{4})?匹配一个连字符和后四位数字(必须一起出现或者不出现)

#\d{5}(?(?=-)-\d{4})  向前查找,找到"-"一起打印-\d{4}或者不打印(?=-向前查找并不消费)


常见问题的正则表达式解决方案:
匹配文件名中的任何字符串:
匹配文件名中的每个字符:
匹配文件名中的字母或者数字字符:
*   匹配文件名中的任何字符串,包括空字符串
? 匹配文件名中的任何单个字符
[...] 匹配[]中所包含的任何字符
[!...] 匹配[]中非感叹号!之后的字符

# ls [ad]*  查找a或者d开头的文件
add.sh  date.sh  diaoyong  diff
#ls log.[0-9]*  查找0-9的字符
#ls [a-z]*  查找a-z的数字

shell的输入与输出:(echo and read cat 管道)
#!/bin/bash
echo -n  "Please input your name:"  -n禁止echo命令输出后换行 
read name     
echo -e "Mr.$name is 20 years!\n\n"  -e允许字符串中转义使用\n换行
转义字符:\c 不换行;\n换行;\t跳格

tee命令:当执行某些命令或者脚本的时候,如果希望把输出保存下来,就将使用tee
-a 表示可以追加到文件
#df | tee -a file
使用tee的好处就是当你在执行任何命令的时候,都可以将显示的结果打印定向到一个普通文件中取。

grep:(全局正则表达式版本)允许对文本文件进行模式查找。
三种变形:grep;egrep;Fgrep
#grep的常用选项:
-c只输出匹配行的计数
-i不区分大小写(只适用于单字符)
-n显示匹配行以及行号
-v显示不包含的匹配行
#grep "86" hello  从hello文件中查找86的行
#grep “48[1-9]” hello 模式匹配
# grep [aA]b hello-1   查找大小写
#grep -i ab hello-1  -i不区分大小写
#grep -E "ab|AB" hello  使用-E参数进行匹配'与/或'运算
#grep ‘^$’hello  查找空行
#grep -s  可以屏蔽错误(当你查找的文件不存在时)
egrep 可以多个字符查找(或的关系)
#egrep "hello|xxb|andy" /etc/passwd

awk格式化报文或从一个大的文本文件中抽取数据包。
awk的简单作用:
抽取域;匹配正则表达式;比较域;想awk传递参数
awk的调用方法:
#awk -F 'command' filename
-F指定分割符,'command'真正的awk命令 filename文件名
同时可以将awk写在文本中,使用awk -f调用

awk脚本:
如果设置了-F选项,则awk每次读一条记录或一行,并使用指定的分隔符指定域。默认使用空格作为分隔符。
awk每次在在文件中读取一行,找到域分隔符,设置其域为n,直到一新行,然后,划分这一行作为一条记录,接着awk再次启动下一行读进程。

awk语句由模式和动作组成,模式可以是任何条件语句或者正则表达式。模式包括两个特殊字段:BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依旧输入文件开始执行。END语句用来在aek完成文本浏览动作后打印输出文本总数和结尾状态标志。如果不特别指明模式,awk总是匹配或打印行数
 实际动作在大括号{}内指明。动作大多数用来打印,但是还是有些更长的代码诸如if和循环语句以及循环退出结构。
 awk中$n代表某一个域,$0代表所有域。一般动作为print
注意:一般使用awk,sed,grep,cut等可以在后面使用tee命令保存哦

awk打印BEGIN和END模式
# netstat -antlp | grep LISTEN | awk '{print $7}' | awk -F/ 'BEGIN {print "Port\tService\n----------------"} {print $1"\t"$2} END{print ".....\nEND of bot"}'
Port    Service
----------------------
1014    rpcbind
1226    sshd

awk注意事项:
确保整个awk命令用单引号括起来。
确保命令内的所有引号成对出现
确保用花括号{}括起动作语句,用()括起条件语句
awk中NF指定的是域的个数,NR指定行数;$NF指定最后一个域的值;$NR指定依次打印一遍行列

匹配符~:为使一域号匹配正则表达式,使用"~"后紧跟正则表达式,也可以使用if语句.awk中if后面的条件用()括起来了。
例如:#awk '{if($4~/xxb/) print $0}'
# cat cat.ip | awk -F"|" '{if($2~/andy/) {print $0}}'   注意:分隔符还是引住
# awk -F "|" '$2 ~ /xxb/' cat.ip    直接过滤查找
# awk -F"|" '$2 !~/xxb/' cat.ip    直接过滤非查找
# awk -F"|" '$2=(!)="xxb" {print $0}' cat.ip  使用精确(过滤)查找
# awk '{if($2>$3) print $0}' grade   判断成绩后进行输出
# awk '{if($2>70) print $0}' grade
# awk '$1~/(xxb|yyy)/ ' grade    打印匹配(或)的整行(print $0)
# awk '{if($2>70 && $3>80) print $0}' grade    打印两个成绩并集(与)
awk内置变量:
NF:支持记录域的个数,在记录被读之后设置
NR:显示行数
FILENAME:显示支持awk脚本实际操作的输入文件名
RS:记录分隔符,缺省为新行(\n)
 
 #awk '(t+=$4) {print $0}; END{print t}' grade   只打印一个最终值 END最终打印
 #awk awk '(t+=$4) {print $0,t}' grade   这样将在最后打印每一列的累加,最后再打印一次最终值
 
 awk中内置的函数:
 gsub(r,s)    在整个$0中用s代替r    类似于sed查找和替换
 index(s,t)  返回s中字符串t的第一位置
 length(s)   返回字符长度  # awk '{print $0,length()}' grade   (其实也可以写在前面的)
 match(s,r) 测试s是否包含匹配r的字符串
 sub(r,s)     用$0中最左边最长的子串代替s
 substr(s,p) 返回字符串s中从p开始的后缀部分
  #awk '{print $0,substr($1,1,2)}' grade    打印$1列的从第1个字符开始打印2个长度
  #awk '{print $0,substr($1,1)}' grade 打印$1列全部,2减去首字母,3减去两个
  
  

 

                                                                                                                  my.oschina.net/xxbAndy/blog

转载于:https://my.oschina.net/xxbAndy/blog/370806

你可能感兴趣的:(awk-grep-sed简单使用总结(正则表达式的应用))