Linux中的正则表达式

Linux中的正则表达式

标签:linux

  • 基础的正则表达式

    • .(一个点)
      [root@localhost ~]# grep 'r..t' /etc/passwd
      上述命令可以找出/etc/passwd中含有’r..t’的行。
    • *
      “*”符号用于匹配前一个字符0次或任意多次
      “*”符号经常和“.”符号加在一起使用,比如“.*”代表任意长度的不包含换行的字符。
    • \{n,m\}

      1. \{n\}匹配前面的字符n次;
      2. \{n,\}匹配前面的字符至少n次以上(含n次);
      [root@localhost ~]# grep 'ro\{0,\}t' /etc/passwd
      root:x:0:0:root:/root:/bin/bash
      operator:x:11:0:operator:/root:/sbin/nologin
      vcsa:x:69:69:virtual console memory owner:/dev:/sbin/
      nologinrpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
      1. \{n,m\}匹配前面的字符n到m次。
    • ^
      这个符号用于匹配开头的字符。比如说“^root”匹配的是以字母root开始的行。
      [root@localhost ~]# grep '^root' /etc/passwd
      root:x:0:0:root:/root:/bin/bash
      1. $
          “$”用于匹配尾部,比如说“abc$”代表的是以abc结尾的行。如果是“^$”则代表该行为空,因为^和$间什么都没有。下例匹配的是以r开头,中间有一串任意字符,以h结尾的行。
        [root@localhost ~]# grep '^r.*h$' /etc/passwd
      2. []
          这是一对方括号,用于匹配方括号内出现的任一字符。在方括号内可以使用“-”号做范围限定:[A-Za-z]。如果限定当前字符不是大写字母A、B、C、D的字符,可以借助^,如右侧所示:[^A-D]。
      3. \
          转义字符。“\”符,这个符号代表转义字符,则如果在[]之间使用-符号的话,可以使用[\-]。
      4. “\<”符号和“\>”符号
          这两个符号分别用于界定单词的左边界和右边界。比如说\<hello用于匹配以“hello”开头的单词;而hello\>则用于匹配以“hello”结尾的单词。还可以使用它们的组合——“\<\>”用于精确匹配一个字符串。所以\<hello\>可精确匹配单词hello,而不是helloworld等。
      5. \d
        匹配一个数字,等价于[0-9]。
        [root@localhost ~]# echo 123 | grep '\d'
        [root@localhost ~]# #没有输出,表示匹配不成功
        #这是因为“\d”是一种Perl兼容模式的表达式,又称作PCRE,要想使用这种模式的匹配符,需要加上-P参数
        [root@localhost ~]# echo 123 | grep -P '\d'
      6. \b
        匹配单词的边界,比如“\bhello\b”可精确匹配“hello”单词。
      7. \B
        匹配非单词的边界,比如hello\B可以匹配“helloworld”中的“hello”。
      8. \w
        匹配字母、数字和下划线,不完全等价于[A-Za-z0-9_],因使用Unicode字符集。
      9. \W
        匹配非字母、非数字、非下划线,等价于[^A-Za-z0-9_]。
      10. \s
        匹配任何空白字符包括空格、制表符、换行符、换页符等等。等价于[ \f\n\r\t\v]。
      11. \S
        匹配任何非空白字符,等价于[^ \f\n\r\t\v]。
  • 扩展的正则表达式(需要使用egrep)
      顾名思义,扩展的正则表达式一定是针对基础正则表达式的一些补充。实际上,扩展正则表达式比基础正则表达式多了几个重要的符号。不过要注意的是,在使用这些扩展符号时,需要使用egrep命令(后面会专门介绍)。

    • “?”符号
        “?”符号用于匹配前一个字符0次或1次,所以“ro?t”仅能匹配rot或rt。
    • “+”符号
        “+”符号用于匹配前一个字符1次以上,所以“ro+t”就可以匹配rot、root等。
    • ()
      “()”符号通常需要和“|”符号联合使用,用于枚举一系列可替换的字符。
      #这样021-88888888和0511 88888888都可以匹配
      ^0[0-9]\{2,3\}(-| )[0-9]\{8\}
      #使用"()"和"|"匹配
      hard、hold或hoodh(ar|oo|ol)d

    • {}下的变量扩展

  • 通配符

    • “*”符号
        这里的“*”就是提到的第一个通配符,代表0个或多个字符。那么之前的*.doc就是指所有以.doc结尾的文件。如果想要找的文档是以字母A开头,则可用A*.doc来查找。在Linux中,列出当前目录中是否存在以.doc结尾的文件,可以使用以下命令:
      [root@localhost ~]# ls -l *.doc
        #该命令执行后,shell先要解析出命令和参数,这里的命令是ls,参数是*.doc,一旦发现了*符号,shell就会将*.doc解析成所有匹配的文件名,然后显示结果。
    • “?”符号
      它作为通配符使用时,代表的是任意一个字符。其写法如下:
      [root@localhost ~]# ls -l A?.doc
    • {}
        “{}”可拥有匹配所有括号内包含的以逗号隔开的字符。例如,下面列出了所有以字母A、B、C开头,以.doc结尾的文件:
      #第一种方法:用“{}”
      [root@localhost ~]# ls -l {A,B,C}.doc
      #第二种方法:用“[]”
      [root@localhost ~]# ls -l [A-C].doc
      #以上两种方法都能满足题意,但是如果要列出以字母AB或者CD开头、以.doc结尾的文件,就只能用“{}”了.
        有意思的是,“{}”还支持嵌套的通配。以“{x,y}”为例,如果x和y各自本身也是通配符,则就变得更强大了,想一想下面例子的含义。
      [root@localhost ~]# ls -l {[A-Z]*.doc,[0-9]??.txt}
    • “^”符号和“!”符号
      两个符号往往和“[]”一起使用,以[^A](或[!A])代表不是A。
    • 通配符的扩展
    [root@localhost ~]# echo {x1,x2,x3}{y1,y2,y3}
    x1y1 x1y2 x1y3 x2y1 x2y2 x2y3 x3y1 x3y2 x3y3
    
    [root@localhost ~]# touch file_{A,B}
    [root@localhost ~]# ls file_{A,B}
    file_A  file_B

    【注意】可能大家已经认识到,通配符和正则表达式之间存在的一些差异。简要地说,正则表达式主要使用在对文件内容的匹配上,而通配符主要是用在文件名的匹配上,可以用这种方法来帮助区别二者。

    • 控制字符
  • 正则表达式示例

    • grep的英文是Global search RegularExpression and print out the line,即全面搜索正则表达式并打印出匹配行。由于正则表达式中含有较多特殊的字符,所以结合grep时,最好使用单引号将正则表达式括起来,以免造成错误。下面前两个命令是有区别的,其中,第二个是精确匹配:
    [root@localhost ~]# grep 'gold' test.txt
    [root@localhost ~]# grep '\<gold\>' test.txt
    
    #搜索以字母g开头包含两个以上o的单词
    
    [root@localhost ~]# grep 'go\{2,\}' test.txt
    • 一些特殊的POSIX字符:
    
    #grep支持一类特殊的POSIX字符,列举如下
    
    
    #[:alnum:]      文字数字字符
    
    
    #[:alpha:]      文字字符
    
    
    #[:digit:]      数字字符
    
    
    #[:graph:]      非空字符(非空格、控制字符)
    
    
    #[:lower:]      小写字符
    
    
    #[:cntrl:]      控制字符
    
    
    #[:print:]      非空字符(包括空格)
    
    
    #[:punct:]      标点符号
    
    
    #[:space:]      所有空白字符(新行,空格,制表符)
    
    
    #[:upper:]      大写字符
    
    
    #[:xdigit:]     十六进制数字(0-9,a-f,A-F)
    
    
    #搜索以大写字母开头的行
    
    [root@localhost ~]# grep ^[[:upper:]] RegExp.txt
    Upper case
    • 使用扩展的正则表达式egrep:
    
    #搜索g和d之间至少有一个o的行#“+”代表匹配前面的字符1次以上(含1次)
    
    [root@localhost ~]# egrep 'go+d' RegExp.txt
    
    #“?”代表匹配前面的字符1次以上
    
    [root@localhost ~]# egrep 'go?d' RegExp.txt
    
    #搜索有glad或gold的行
    
    [root@localhost ~]# egrep 'glad|gold' RegExp.txt
  • 文本处理工具 sed
      sed并不会改变原文件本身,而只是对流经sed命令的文本进行修改,并将修改后的结果打印到标准输出中(也就是屏幕)。sed处理文本时是以行为单位的,每处理完一行就立即打印出来,然后再处理下一行,直至全文处理结束。
      要想保存修改后的文件,必须使用重定向生成新的文件。如果想直接修改源文件本身则需要使用“-i”参数。
      使用sed修改文件流的方式如下:

    `sed [options] 'command' file`
    `#使用-e参数和分号连接多编辑命令`
    
    #下面的例子就是演示了在将this改为That的同时,还要将line改为LINE#两个编辑命令前都要使用-e参数,如果有更多的编辑需求,以此类推即可
    
    [root@localhost ~]# sed -e 's/this/That/g' -e 's/line/LINE/g' test.txt
    
    #上面的命令可以用分号改写为:
    
    [root@localhost ~]# sed 's/this/That/g ; s/line/LINE/g' test.txt

    sed具体的操作:

    • 使用d命令可删除指定的行
    
    #将file的第一行删除后输出到屏幕
    
    [root@localhost ~]# sed '1d' test.txt
    
    #由于sed默认不修改原文件,如果希望保存修改后的文件则需要用重定向
    
    sed '1d' test.txt > saved_file#如果想直接修改文件,使用-i参数
    
    #test -i '1d' file
    
    
    #删除指定范围的行(第1行到第5行)
    
    [root@localhost ~]# sed '1,3d' test.txt
    
    #删除指定范围的行(第一行到最后行)
    
    [root@localhost ~]# sed '1,$d' test.txt
    
    #删除最后一行
    
    [root@localhost ~]# sed '$d' test.txt
    
    #删除除指定范围以外的行(只保留第5行)
    
    [root@localhost ~]# sed '5!d' test.txt
    
    #删除空行
    
    [root@localhost ~]#sed '/^$/d' Sed.txt
    • 使用s命令可将查找到的匹配文本内容替换为新的文本
    
    #每行最多匹配2个line,并改为LINE,可用如下方式
    
    [root@localhost ~]# sed 's/line/LINE/2' Sed.txt
    
    #s命令利用g选项,可以完成文本所有匹配值的替换
    
    [root@localhost ~]# sed 's/line/LINE/g' Sed.txt
    
    #只替换文本每行开头的this为that
    
    [root@localhost ~]# sed 's/^this/that/' Sed.txt
    • 使用y命令可进行字符转换,其作用为将一系列字符逐个地变换为另外一系列字符
      #该命令会将file中的O转换为N、L转换为E、D转换为W#注意转换字符和被转换字符的长度要相等,否则sed无法执行
      sed 'y/OLD/NEW/' file
    • 使用i或a命令插入文本,其中i代表在匹配行之前插入,而a代表在匹配行之后插入
    
    #使用a在第二行后插入文本
    
    [root@localhost ~]# sed '2 a Insert' Sed.txt
    
    #在匹配行的上一行插入问题(注意/和\)
    
    [root@localhost ~]# sed '/Second/ i \Insert' Sed.txt
    this is line 1, this is First line
    Insert
    this is line 2, the Second line, Empty line followed
    • 使用r命令可从其他文件中读取文本,并插入匹配行之后(注意命令的顺序)
      #将/etc/passwd中的内容读出放到Sed.txt空行之后
      [root@localhost ~]# sed '/^$/ r /etc/passwd' Sed.txt
    • 使用p命令可进行打印,这里使用sed命令时一定要加-n参数,表示不打印没关系的行
    
    #打印出文件中指定的行
    
    [root@localhost ~]# sed -n '1p' Sed.txt
    this is line 1, this is First line
    
    #使用p命令,则只打印实际处理过的行,简化了输出(使用-n参数)
    
    [root@localhost ~]# sed -n 's/the/THE/p' Sed.txt
    • 想保存文件,除了之前提到的两种方法外(使用重定向或-i参数),还可以使用w命令将结果保存到外部指定文件
      [root@localhost ~]# sed -n '1,2 w output' Sed.txt
    • sed脚本
    
    #该sed脚本的作用是将全文的this改为THAT,并删除所有空行
    
    [root@localhost ~]# cat Sed.rules
    s/this/THAT/g
    /^$/d
    
    #使用-f参数指定该脚本并应用于Sed.txt
    
    [root@localhost ~]# sed -f Sed.rules Sed.txt
    • sed中的高级替换
        想要修改匹配行的下一行的文本,就需要使用n命令了。该命令的作用在于读取匹配行的下一行,然后再用n命令后的编辑指令来处理该行。在下面的Sed.txt文件中有一行空白行,现在想将该空格行的下一行中的line改为LINE,而文本中其他部分保持不变,操作如下:

      [root@localhost ~]# sed '/^$/{n;s/line/LINE/g}' Sed.txt
      this is line 1, this is First line
      this is line 2, the Second line, Empty line followed
      this is LINE 4, this is Third LINE
      this is line 5, this is Fifth line
    • sed脚本常用参数以及正则表达式总结
      常用命令:


      sed常用参数:

      sed常用正则表达式匹配:
  • 文本处理工具awk
      awk是一种编程语言。awk认为文件都是结构化的,也就是说都是由单词和各种空白字符组成的,这里的“空白字符”包括空格、Tab,以及连续的空格和Tab等。每个非空白的部分叫做“域”,从左到右依次是第一个域、第二个域,等等。$1、$2分别用于表示对应的单个域,$0则表示全部域。

    [root@localhost ~]# cat Awd.txt
    john.wang       Male    30      021-11111111
    lucy.yang       Female  25      021-22222222
    jack.chen       Male    35      021-33333333
    lily.gong       Female  20      021-44444444    ShangHai
    • 打印指定域
      只打印姓名和电话号码
    [root@localhost ~]# awk '{print $1, $4}' Awd.txt
    john.wang 021-11111111
    lucy.yang 021-22222222
    jack.chen 021-33333333
    lily.gong 021-44444444#

    打印全部内容

    [root@localhost ~]# awk '{print $0}' Awd.txt
    john.wang       Male    30      021-11111111
    lucy.yang       Female  25      021-22222222
    jack.chen       Male    35      021-33333333
    lily.gong       Female  20      021-44444444    ShangHai
    • 指定打印分隔符
        默认情况下awk是使用空白字符作为分隔符的,但是也可以通过-F参数指定分隔符,来区分不同的域(有点像cut命令)。

      [root@localhost ~]# awk -F. '{print $1, $2}' Awd.txt
      john wang       Male    30      021-11111111
      lucy yang       Female  25      021-22222222
      jack chen       Male    35      021-33333333
      lily gong       Female  20      021-44444444    ShangHai
    • 内部变量NF
        如果要获得文件的列数,通过awk的内部变量NF可以简单地做到这点。

      
      #使用默认分隔符[root@localhost ~]# awk '{print NF}' Awd.txt
      
      4
      4
      4
      5
      [root@localhost ~]# awk -F. '{print NF}' Awd.txt
      2
      2
      2
      2
    • 打印固定域
        通过内部变量可以简单地得到每行的列数,而如果在NF之前加上 使 NF就能打印出最后一行。
    
    #打印最后一行
    
    [root@localhost ~]# awk '{print $NF}' Awd.txt
    
    #用$(NF-1)打印倒数第二行
    
    [root@localhost ~]# awk '{print $(NF-1)}' Awd.txt
    • 截取字符串
      可以使用substr()函数对指定域截取字符串,规则如下:
      substr(指定域,第一个开始字符的位置,第二个结束的位置)
      #其中第二个结束的位置可以为空,这样默认输出到该域的最后一个字符
      #该例中,第二个结束位置省略,所以结束位置为第一个域的最后一个字符

      [root@localhost ~]# cat Awd.txt | awk '{print substr($1,6)}'
      wang
      yang
      chen
      gong
    • 确定字符串的长度
      使用内部变量length可以确定字符串的长度,示例如下:
      [root@localhost ~]# cat Awd.txt | awk '{print length}'
    • 列和

      
      #求年龄的和
      
      [root@localhost ~]# cat Awd.txt | awk 'BEGIN{total=0}{total+=$3}END{print total}'
      
      #求平均年龄
      
      [root@localhost ~]# cat Awd.txt | awk 'BEGIN{total=0}{total+=$3}END{print total/NR}'
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值