zoukankan      html  css  js  c++  java
  • BASH 正则表达式和文本处理工具

    本节内容

    1.  什么是正则

    2.  grep

    3.  sed

    4.  awk

    5.  其他补充 

    一  什么是正则

    正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法

    或者说:

    正则就是用来描述一类事物的规则

    生活中处处都是正则:

    比如我们描述:4条腿  你可能会想到四条腿的动物或者桌子、椅子等

    继续描述:4条腿,活的 就剩下四条腿的动物这一类了

     

    在Linux中,通配符是由shell解释的,而正则表达式则是由命令解释的

    下面我们就为大家介绍三种文本处理工具/命令:

    grep, sed, awk,它们三者均可以解释正则

    二  grep

    grep -选项

    '''
    -n  显示行号
    -o  只显示匹配内容
    -q  静默模式,没有任何输出,得用$?来判断成功没有,即有没有过滤到想要的内容
    -l  如果匹配成功,则将文件名打印出来,失败则不打印,通常 -rl 一起用 grep -rl 'root /test
    -A n  如果匹配成功,则将匹配行及其后n行一起打印出来
    -B n  如果匹配成功,则将匹配行及其前n行一起打印出来
    -A n  如果匹配成功,则将匹配行及其前后n行一起打印出来
    日志分析时会用到
    
    -c  如果匹配成功,则将匹配到的行数打印出来
    -E  等于egrep,扩展
    -i  忽略大小写
    -v  取反,不匹配
    -w  匹配单词
    '''
    grep -n 'root' /etc/passwd
    grep -o 'root' /etc/passwd
    grep -q 'root' /etc/passwd  && echo $?
    grep -l 'root' /etc/passwd
    grep -A n  'root' /etc/passwd
    grep -B n  'root' /etc/passwd
    grep -C n  'root' /etc/passwd
    grep -c n  'root' /etc/passwd
    grep -i  'ROOT' /etc/passwd
    grep -v  'ROOT' /etc/passwd
    实例
    [root@localhost ~]# cat a.txt 
    root123
    root
    123root
    root 123
    root_123
    [root@localhost ~]# grep -w 'root' a.txt
    root
    root 123
    [root@localhost ~]# 

    正则介绍

    ^ 行首 

    [root@localhost ~]# grep '^root' test     # 匹配以root开始的行
    root:x:0:0:root:/root:/bin/bash

    $ 行尾

    [root@localhost ~]# grep 'bash$' test   # 过滤出能登录shell的用户
    root:x:0:0:root:/root:/bin/bash

    .  除了换行符以外的任意单个字符

    [root@localhost ~]# grep '^b.n' test    # 以b开头,第二个任意字符,第三个n,开头的行
    bin:x:1:1:bin:/bin:/sbin/nologin

    * 前导字符的零个或多个

    [root@localhost ~]# grep 'ab*' a.txt    # 筛选以a开头,b重复零次或多次的行

    a
    ab
    abb
    abnb   # 包含ab了,所以abnb也输出了

    .* 表示所有字符

    扩展 egrep

    ? 前导字符零个或一个

    + 前导字符一个或多个

    [root@myname ~]# egrep 'ab+' a.txt
    ab
    abb
    abnb

     

    {n} 前导字符 n个

    [root@myname ~]# egrep 'ab{1}' a.txt
    ab
    abb
    abnb

     

    [] 组内的任一字符,  .  除了换行符以外的任意单个字符

    [^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)

    ^[^] 非字符组内的字符开头的行

    [a-z] 小写字母

    [A-Z] 大写字母

    [a-Z] 小写和大写字母

    [0-9] 数字

    注意的一点:如果想要匹配的字符是 - 本身,必须放到最后去[123123-]

    egrep 'compan(y|ies)' a.txt   或

    egrep  -e 'company' -e 'companies'  a.txt  指定多个规则

    注意:grep 是匹配到那一行,与匹配到的字符含义不同

     

    例子 ssh有效配置

    grep  -v   '^#'   /etc/ssh/sshd_config  | grep -v  '^# *$'

    小结

    """
    单个
    .除了换行符以外的任意单个字符
    [] 组内的任意单个字符
    
    可多个
    *     左边的那一个字符有0个到无穷个
    +     左边的那一个字符有1个到无穷个
    ?     左边的那一个字符有0个到1个
    {n}   左边的那一个字符有n个
    {n,m} 左边的那一个字符有n个到m个
    {n,}  左边的那一个字符有n个到无穷个
    """
    三  sed

    流编辑器 stream editor,是以行为单位的处理程序

    语法:

    sed  [options]  'command'  in_file(s)

    -n  not 静默模式,默认不打印到屏幕上

    -e  多个选项

    -i   insert 直接修改源文件

    -f   如,-f pattern.sed   匹配规则从文件读取

    command部分

    定位 执行命令,分为行号定位和正则定位/ /

     

    行号定位:

    [root@myname ~]# sed  '3d'  test        # 删除第三行

    [root@myname ~]# sed -n '3p' test     # 打印第三行
    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    [root@myname ~]# sed '2c 123' test   # 更改第二行为 123
    root:x:0:0:root:/root:/bin/bash
    123

    [root@myname ~]# sed  '2i 123'  test    # 第二行前插入一行

    [root@myname ~]# sed '2a 123' test     # 第二行后附加一行
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    123

    [root@myname ~]# sed  '1,3d'  test     # 删一到三行

    [root@myname ~]# sed  '1d;3d'  test  # 删第一和第三行

     

    正则定位  / / :

    [root@myname ~]# sed  '/^root/d'  test    # 删除以root开始的行

     

    常用替换:

    s 三个/ / /原则,格式   's/匹配条件/更改后内容/g'

    sed 's/sb/SB/' test        匹配到的行只改第一个

    sed 's/sb/SB/g' test     匹配到的行都修改

    sed '/alex/s/sb/SB/g' test     匹配到alex的行,把所有sb改为SB

     

    扩展sed 必加-r,就相当于只用egrep

    sed   -r   's/^[0-9]([a-A]{3})/sb/SB/g'   test

    sed -r 's/(^[a-Z]+)([^a-Z])/12/g'       不指定具体某行时,代表所有行, 1 取第一个()值,2取第二个()值

    实例:

    需求第一个单词和第二个单词换换位置,关键是找非单词

    sed -r 's/^()()()()/3214/g' test

    sed -r  's/^([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)/3214/g'   test

    Sed作业:以/etc/passwd文件为模板
    
    1,删除文件每行的第一个字符。
    
    2,删除文件每行的第二个字符。
    
    3,删除文件每行的最后一个字符。
    
    4,删除文件每行的倒数第二个字符。
    
    5,删除文件每行的第二个单词。
    
    6,删除文件每行的倒数第二个单词。
    
    7,删除文件每行的最后一个单词。
    
    8,交换每行的第一个字符和第二个字符。
    
    9,交换每行的第一个字符和第二个单词。
    
    10,交换每行的第一个单词和最后一个单词。
    
    11,删除一个文件中所有的数字。
    
    12,删除每行开头的所有空格。
    
    13,用制表符替换文件中出现的所有空格。
    
    14,把所有大写字母用括号()括起来。
    
    15,打印每行3次。
    
    16,隔行删除。
    
    17,把文件从第2行到第5行复制到第7行后面。(选做题)
    
    18,把文件从第2行到第5行移动到第7行后面。(选做题)
    
    19,只显示每行的第一个单词。
    
    20,打印每行的第一个单词和第三个单词。
    
    21,将格式为    mm/yy/dd    的日期格式换成   mm;yy;dd
    
    22, a.txt内容
        ABC
        DEF
        XYZ
        通过SED实现tac命令
        tac a.txt
        XYZ
        DEF
        ABC
    
    1. sed -r 's/^(.)(.*)/2/' /etc/passwd
    2. sed -r 's/^(.)(.)(.*)/13/' /etc/passwd
    3. sed -r 's/(.*)(.)$/1/' /etc/passwd
    4. sed -r 's/(.*)(.)(.)$/13/' /etc/passwd
    5. sed -r 's/^([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)/124/' /etc/passwd
    6. sed -r 's/([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)$/134/' /etc/passwd
    7. sed -r 's/([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)$/123/' /etc/passwd
    8. sed -r 's/^(.)(.*)(.)$/321/' /etc/passwd
    9. sed -r 's/^(.)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)/42315/' /etc/passwd
    10. sed -r 's/^([a-Z]+)([^a-Z]+)(.*)([^a-Z]+)([a-Z]+)$/52341/' /etc/passwd
    11. sed -r 's/[0-9]//g' /etc/passwd
    12. sed -r 's/^ *//g' /etc/passwd
    13. sed -r 's/ /	/g' /etc/passwd
    14. sed -r 's/[A-Z]/(&)/g' /etc/passwd
    15. sed 'p;p' /etc/passwd
    16. sed '1~2d' /etc/passwd
    
    选做题17-18:文件内容
    [root@MiWiFi-R3-srv ~]# cat test 
    2222222222
    4444444444
    6666666666
    888888888888
    
    17.sed '2h;3,5H;7G' test 
    
    18. sed '2h;3,5H;2,5d;7G' test 
    
    19. sed -r 's/^([a-Z]+)([^a-Z]+)(.*)/1/' /etc/passwd
    20. sed -r 's/^([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)/523416/' /etc/passwd
    21. 
    22. sed -r '{1h;1d;2G;2h;2d;3G;3h}'
    23. 
    echo "2012/12/11" |sed -r 's///:/g'
    echo "2012/12/11" |sed -r 's#/#:#g'
    echo "2012/12/11" |sed -r 's@/@:@g'
    
    sed作业
    sed作业

    小结:

    sed 流编辑器,以行为单位处理文档,可完成匹配条件的行操作,如查找相应行,替换相应字符

    四 awk

    当文本的结构化特别清晰的时候,可以awk -F切分字符,进行切分,如 awk -F:  'commands' files

    awk -F: '$1 == "root"{print $1,NR,NF}' /etc/passwd
    awk -F: 'NR>20 || NR<3{print $1,$3,$NF}' /etc/passwd
    awk -F: 'NR>1 && NR<3{print $1,NR,NF}' /etc/passwd
    awk -F: 'NR>1 && NR<4{print $1,NR,NF}' /etc/passwd
    awk -F: '$1~/^r/{print $1,NR,NF}' /etc/passwd
    awk -F: '/^root/{print $1,NR,NF}' /etc/passwd

    username=root
    awk -v var=$username -F: '$1 == var{print $1,NR,NF}' /etc/passwd

    语法:

    awk  [options]  'commands' files

    • -F 定义分割字符,默认的分割字符是连续的空格或制表符

    • 使用$1, $2, $3等顺序表示files中每行以间隔符号分隔的各列不同域

    • NF变量表示当前记录的字段数,number of fields

    • -v 定义变量并赋值 也可以借用次方式从shell变量中引入

    • commands 执行部分用 {},如awk '{print NR, $1}' test

    NR变量定址  NR表示awk读入的行号,number of row

    [root@myname ~]# ip_addr=`ifconfig | awk 'NR==2{print $2}'`
    [root@myname ~]# echo $ip_addr
    192.168.254.141

    正则定址/ /     '/正则表达式/{print $1}'

    [root@myname ~]# awk -F: '/nologin$/{print $1}' test
    bin
    daemon
    adm

    五  其他补充

    [root@myname ~]# cat test | sort | uniq    # 排序去重
    1111111111111111
    2222222222222222
    3333333333333333
    4444444444444444

    [root@myname ~]# cat /etc/passwd |cut -d: -f1     # cut 轻量级切割
    root
    bin
    daemon

    [root@myname ~]# find / -size +2M -type f -name *.txt   # 查找

    更多信息参考

    http://www.cnblogs.com/linhaifeng/p/6596660.html

  • 相关阅读:
    ABP dynamic API
    SQL语句 还原未知逻辑名称数据库
    SQL 还原数据库
    使用开源项目集锦
    webp性能测评
    js通过继承实现私有函数
    js组合继承和寄生组合式继承比较
    JS中循环绑定遇到的问题及解决方法
    JS学习之事件流
    OpenGL利用模板测试实现不规则裁剪
  • 原文地址:https://www.cnblogs.com/jonathan1314/p/7597135.html
Copyright © 2011-2022 走看看