• 正则、grep、sed、awk


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

    正则

    正則表達式主要分为基础正则和扩展正则。注意,正则和一般命令行输入的命令的通配符不同。正则仅仅使用于支持这样的表示法的工具,如: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,} 同上,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="[, ]”} 

    PS要使分隔符在第一行生效,需加BEGINkeyword


    输出的时候,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 = "[, 	]"
    }
    {
    	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})|(1[0-9]{2,2})|(2[0-4][0-9])|(25[0-5]))/)
    			printf $i"	"
    		if (i == NF) 
    			printf "
    "
    	}
    }
    


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



    參考:
    [1]:鸟哥的linux
  • 相关阅读:
    Spring service本类中方法调用另一个方法事务不生效问题(转载)
    JVM垃圾收集器
    LInkedHashMap实现最近被使用(LRU)缓存
    HTML模板与iframe框架
    Mybatis中常用sql语句
    从零到一: 后端接口文档
    Mysql日期处理
    Java-集合框架与数组的实际应用-组装Json字符串
    Mysql查询之 指定顺序排序
    Eclipse中复制项目后,怎么更改项目名等相关配置?
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4384772.html
Copyright © 2020-2023  润新知