加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则、grep、sed、awk

发布时间:2020-12-14 01:34:15 所属栏目:百科 来源:网络整理
导读:每次用到正则都要蛋疼一下,索性总结一下在这里。 正则 正则表达式主要分为基础正则和扩展正则。注意,正则和一般命令行输入的命令的通配符不同。正则只使用于支持这种表示法的工具,如:vi,grep,sed、awk。而ls等命令不支持这种表示,只能使用bash自身的通

每次用到正则都要蛋疼一下,索性总结一下在这里。

正则

正则表达式主要分为基础正则和扩展正则。注意,正则和一般命令行输入的命令的通配符不同。正则只使用于支持这种表示法的工具,如:vi,grep,sed、awk。而ls等命令不支持这种表示,只能使用bash自身的通配符。

基础部分:

[abc]匹配括号中的一个

[^abc]匹配非括号中的一个(取反)

^word以word开头

word$以word结尾

[n1-n2] 从n1到n2之间的所有连续字符.

注意:这个连续与否,与ASCII编码有关,

不同的语系编码方式不同:

LANG=C:0 1 2 3 …A B C …a b c

LANG=zh_CN.gb2312: 0 1 2…a A b B ..z Z

上面是编码顺序,正则使用时,需留意语系环境,通常为兼容POSIX,使用“C”语系。"export LANG=C"

特殊符号如: [:alnum:]等,就是为了避免语系问题。其他如下图:


[0-9]或d表示一个数字

s一个空格,tab,回车或一个换行符

w 表示“一个单词字符”,等同于[0-9A-Za-z_]

.小数点,代表一定有一个任意字符.单独使用需要表示小数点时,需转义.

*重复前一个0到无穷多次

{n,m}连续前面的字符n到m个

同上,n个以上

注意:在shell里{和}需转义{}


扩展正则:

+:重复一个或一个以上的前一个RE字符

?: 零个或一个前一个RE字符

|: 或方法

():组方法,通常和上述几个结合使用,如:a(b|c)d表示 abd或acd,a(xyz)+b,可以匹配axyzxyzxyzb

注意:!和<>不是正则的特殊字符



grep 几个常用参数:

-v:把满足条件取反的信息输出

-i:忽略大小写

-n:显示行号

grep通常是以行为单位输出,但可以这样:

-o:仅仅输出符合要求的部分

egrep,grep升级版,支持扩展正则

sed

sed是按一次处理一行的方式进行的。sed把当前正在处理的行保存在一个叫做模式空间(pattern space)的临时缓存里,处理完成后根据是否满足要求打印输出。然后再读入下一行到这个临时缓存里,直到最后一行。因此,sed不会修改或破坏初始文件。

基本用法,详见:sed简明教程

awk

上古时期的神器,用好了依然称手

有些版本差异,但大致相同:旧awk、新awk(nawk)、gnu awk(gawk)、POSIX awk等

awk不把输入数据看成一个无穷无尽的字符串,而是把它看作一种结构。默认情况下,把每行看成一个记录(record),并以换行符终止。

这个记录分隔符保存在内置变量ORS和RS里分别表示,输出和输入的记录分隔符。

而对于每一个记录,以域(field)为单位分隔,默认情况下,域分隔符为空格符,由内置变量FS保存,每个域依次对应变量$1、$2…而$0表示一个整行。

设置FS,即可改变默认分隔符

eg:{FS=“:”}多个的话:{FS="[,t]”}

PS要使分隔符在第一行生效,需加BEGIN关键字

输出的时候,OFS保存的默认输出域分隔符,默认为空格

eg:{print $1,$2},默认以空格分隔输出。

awk命令由模式(pattern)和操作(action)组成。

awk 'pattern {action}'

模式控制awk对一行输入做什么样的操作,包括一个正则表达式,一个产生正确或者错误条件的表达式,或者他们的组合。当读入一个模式表达式时,有一个隐含的if语句。

操作封装在花括号里。花括号里多个动作以换行符或者分号分隔

匹配操作符,~,用来与一行或一个域里的表达式匹配

eg: awk ‘$1 ~ /xxx/‘ file

反向的话,!~ 即可。

awk脚本

流程控制,变量,操作符等和其他脚本大同小异。注意它特殊的BEGIN和END段。

最近处理一个文本,感觉到awk的高效,如下:

以行为单位过滤出其中的IP地址:

要得到:

awk初体验:

#!/usr/bin/awk -f
BEGIN {
	FS = "[,t]"
}
{
	for(i = 1; i <= NF; i++) 
	{
		if ($1 == "#")
			continue
		if ($i ~ /((([0-9]{1,2})|(1[0-9]{2,2})|(2[0-4][0-9])|(25[0-5])).){3}(([0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))/)
			printf $i"t"
		if (i == NF) 
			printf "n"
	}
}


PS:MacOS里有个小坑,开头的路径是/usr/bin/awk,而不是linux下的/bin/awk



参考:
[1]:鸟哥的linux
[2]: awk简明教程

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读