1、正则表达式

  • 基本的正则表达式 BRE(basic regluar expression)
    • ^$.[ ]*
      • ^: 用于正则表达式最左侧,如”^oldboy“,匹配以oldboy开头的行
      • $: 用于正则表达式最右侧,如oldboy$“,匹配以oldboy结尾的行
      • ^$ :组合表示空行
      • .:匹配任意一个且只有一个字符,不能匹配空行
      • \:转义字符,让特殊含义的字符,还原特殊含义字符本意。例如:. 表示.
      • *: 匹配前一个字符(连续出现)0次以上,重复0次代表空,即匹配所有内容
      • .*:组合符,匹配任意长度字符
      • ^.*:组合符,匹配以任意多个字符开头的内容
      • .*$:组合符,匹配以任意多个字符结尾的内容
      • [abc]:匹配[ ]内部任意字符,可以写成[a-c]
      • [^abc]:匹配除了[ ]内部字符之外的任意字符。^表示取反。
      • <pattern>:匹配完整内容
      • <>:定位单词的左侧或右侧,如<chao>可以找出the chao ge,找不出yuchao
      • 特殊通配符
        | 符号 | 作用 | | —- | —- | | [[:upper:]] | 所有大写字母 | | [[:lower:]] | 所有小写字母 | | [[:alpha:]] | 所有字母 | | [[:digit:]] | 所有数字 | | [[:alnum:]] | 所有的字母和数字 | | [[:space:]] | 所有的空白字符 | | [[:punct:]] | 所有标点符号 |
  • 基本正则表达式主要作用
    • 匹配字符
    • 匹配字符次数

位置锚定

  • 扩展的正则表达式 ERE (extended regular expression)
    • ERE 在BRE的基础上,增加了(){}?+|等字符
    • 扩展正则必须用 grep -E 才能生效
      | 字符 | 作用 | | —- | —- | | + | 匹配前一个字符1次或多次,前面字符至少出现1次 | | [:/]+ | 匹配括号内的”:”或者”/“字符1次或多次 | | ? | 匹配前一个字符0次或1次,前面字符可有可无 | | &#124; | 表示或者,同时过滤多个字符串 | | () | 分组过滤,被括起来的内容表示一个整体 | | a{n,m} | 匹配前一个字符最少n次,最多m次 | | a{n,} | 匹配前一个字符最少n次 | | a{n} | 匹配前一个字符正好n次 | | a{,m} | 匹配前一个字符最多m次 |
  1. grep命令使用参数 -E即可支持正则表达式
  2. egrep不推荐使用,使用grep -E替代
  3. grep不加参数,得在特殊字符前面加"\"反斜杠,识别为正则

2、正则表达式的意义

  • 处理大量字符串
  • 处理文本
    • 通过特殊符号的辅助,可以让linux管理员快速过滤、替换、出来吧所需要的字符串、文本,让工作更高效。
  • 正则表达式 是一套规则和方法,以行为单位 ,一次处理一行
  • linux仅三剑客(sed awk grep)支持,其它命令不支持。

3、Linux三剑客

  • grep: 文本过滤工具, (模式,pattern)工具
  • sed : stream editor,流编辑器;文本编辑工具
  • awk : Linux的文本报告生成器(格式化文本),gawk

4、grep与正则表达式

4.1 grep
  • Global search REgular expression and Print out the line.
  • 作用:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,打印匹配到的行
  • 模式:由正则表达式的**元字符****文本字符**所编写出的**过滤条件**
    5.1.1grep 参数说明
    | 参数 | 用途 | | —- | —- | | -v | — invert -match ;排除匹配结果 显示未被匹配到的行。 | | -n | 显示匹配到的行与行号 | | -i | 不区分大小写;ignorecase | | -c | 只统计匹配到的行数 | | -E | 使用Egrep命令,支持扩展正则表达式 | | —color=auto | 为grep过滤结果添加颜色 | | -w | 完整匹配,字符串精确匹配,整个单词 | | -o | 只输出匹配到的内容 |
  1. [root@MiWiFi-R3-srv ~]# grep -i "root" pwd.txt -n #不区分大小写,显示匹配到的内容与行号
  2. 1:root:x:0:0:root:/root:/bin/bash
  3. 10:operator:x:11:0:operator:/root:/sbin/nologin
  1. [root@MiWiFi-R3-srv ~]# grep -i "root" pwd.txt -c #只输出匹配到的行数
  2. 2
  1. [root@MiWiFi-R3-srv ~]# grep -i "root" pwd.txt -w #完整匹配,字符串精确匹配,整个单词
  2. root:x:0:0:root:/root:/bin/bash
  3. operator:x:11:0:operator:/root:/sbin/nologin
  1. [root@MiWiFi-R3-srv ~]# grep -i "root" pwd.txt -o # 只输出匹配到的内容
  2. root
  3. root
  4. root
  5. root

4.2 正则表达式实践(grep)
  • 准备测试文件

    1. [root@MiWiFi-R3-srv ~]# cat luffy.txt -n
    2. 1 I am oldboy teacher.
    3. 2 I teach linux.
    4. 3 I like python.
    5. 4
    6. 5 My qq is 877348180.
    7. 6
    8. 7 My name is chaoge.
    9. 8
    10. 9 Our school website is http://oldboyedu.com
    11. 10
    12. 11
    13. 12
  • ^ 符号

    • 1、输出所有以m开头的行
  1. [root@MiWiFi-R3-srv ~]# grep "^m" luffy.txt -in
  2. 5:My qq is 877348180.
  3. 7:My name is chaoge.
  • 2、输出所有以i开头的行
    1. [root@MiWiFi-R3-srv ~]# grep "^i" luffy.txt -in
    2. 1:I am oldboy teacher.
    3. 2:I teach linux.
    4. 3:I like python.
  • $

    • 1、输出所有以r结尾的行

      1. [root@MiWiFi-R3-srv ~]# grep -i -n "r$" luffy.txt
      2. 1:I am oldboy teacher
    • 2、输出所以以m结尾的行

      1. [root@MiWiFi-R3-srv ~]# grep -i -n "m$" luffy.txt
      2. 9:Our school website is http://oldboyedu.com
    • 3、输出所有以”.”结尾的行,注意用转义符

      1. [root@MiWiFi-R3-srv ~]# grep -i -n "\.$" luffy.txt
      2. 2:I teach linux.
      3. 3:I like python.
      4. 5:My qq is 877348180.
      5. 7:My name is chaoge.
  • ^$组合符
    • 1、找出文件的空行,以及行号
      1. [root@MiWiFi-R3-srv ~]# grep "^$" luffy.txt -n
      2. 4:
      3. 6:
      4. 8:
      5. 10:
      6. 11:
      7. 12:
  • .点符号

    • “.”表示任意一个字符,有且只有一个,不含空行

      1. [root@MiWiFi-R3-srv ~]# grep "." luffy.txt -n
      2. 1:I am oldboy teacher
      3. 2:I teach linux.
      4. 3:I like python.
      5. 5:My qq is 877348180.
      6. 7:My name is chaoge.
      7. 9:Our school website is http://oldboyedu.com
    • 找出任意一个三位字符,包含ac

      1. [root@MiWiFi-R3-srv ~]# grep ".ac" luffy.txt -n
      2. 1:I am oldboy teacher
      3. 2:I teach linux.
  • \转义符
    • 1.找出文中所有的点”.”
      1. [root@MiWiFi-R3-srv ~]# grep "\." luffy.txt -n
      2. 2:I teach linux.
      3. 3:I like python.
      4. 5:My qq is 877348180.
      5. 7:My name is chaoge.
      6. 9:Our school website is http://oldboyedu.com
  • *
    • 1.找出前一个字符0次或多次,找出文中出现”i”的0次或多次
      1. [root@MiWiFi-R3-srv ~]# grep "i*" luffy.txt -n #匹配所有行。
      2. 1:I am oldboy teacher
      3. 2:I teach linux.
      4. 3:I like python.
      5. 4:
      6. 5:My qq is 877348180.
      7. 6:
      8. 7:My name is chaoge.
      9. 8:
      10. 9:Our school website is http://oldboyedu.com
      11. 10:
      12. 11:
      13. 12:
  • .*组合符
    • .表示任意一个字符,*表示匹配前一个字符0次或多次,因此放一起,代表匹配所有内容,以及空格
      1. [root@localhost ~]# grep ".*" luffy.txt -n
      2. 1:1:I am oldboy teacher
      3. 2:2:I teach linux.
      4. 3:3:I like python.
      5. 4:4:
      6. 5:5:My qq is 877348180.
      7. 6:6:
      8. 7:7:My name is chaoge.
      9. 8:8:
      10. 9:9:Our school website is http://oldboyedu.com
      11. 10:10:
      12. 11:11:
      13. 12:12:
  • 贪婪匹配:这种匹配相同字符到最后一个字符的匹配方式,称之为贪婪匹配
    例如:
    • ^.*o 匹配所有行中含有O的行,每行匹配到含有字母o结束。
      1. [root@localhost ~]# grep "^.*o" luffy.txt -i
      2. 1:I am oldboy teacher
      3. 3:I like python.
      4. 7:My name is chaoge.
      5. 9:Our school website is http://oldboyedu.com
  • 非贪婪匹配:匹配到第一个符合条件的结果就停止匹配,仅匹配到一个结果

  • []:中括号,表示匹配中括号中任意一个字符。
    • [a-z]匹配所有小写单个字母
    • [A-Z]匹配所有单个大写字母
    • [a-zA-Z]匹配所有的单个大小写字母
    • [0-9]匹配所有单个数字
    • [a-zA-Z0-9]匹配所有数字和字母
  • [^a-z]:中括号内^表示取反。
    1. [root@localhost ~]# grep '[^a-z]' luffy.txt
    2. 1:I am oldboy teacher
    3. 2:I teach linux.
    4. 3:I like python.
    5. 4:
    6. 5:My qq is 877348180.
    7. 6:
    8. 7:My name is chaoge.
    9. 8:
    10. 9:Our school website is http://oldboyedu.com
    11. 10:
    12. 11:
    13. 12:

4.3扩展正则表达式实践
  • +号:示匹配前一个字符1次或多次,必须使用grep -E 扩展正则

    1. [root@localhost ~]# grep -E "l+" luffy.txt -n
    2. 1:1:I am oldboy teacher
    3. 2:2:I teach linux.
    4. 3:3:I like python.
    5. 9:9:Our school website is http://oldboyedu.com
  • ?符:匹配前一个字符0次或1次

    1. [root@localhost ~]# grep -E "bo?y" luffy.txt -n
    2. 1:1:I am oldboy teacher
    3. 9:9:Our school website is http://oldboyedu.com
  • |符:正则中是或者的意思

    • 找出系统中的txt文件,且名字里包含a或b的字符
      1. [root@MiWiFi-R3-srv ~]# find / -maxdepth 3 -type f -name "*.txt" | grep -i -E "a|b"
      2. /home/yanguiqiang/mybook.txt
      3. /data/my1.txt
      4. /data/my2.txt
      5. /data/my3.txt
      6. /data/my4.txt
      7. /data/my5.txt
      8. /data/my6.txt
      9. /data/my7.txt
      10. /data/my8.txt
      11. /data/my9.txt
  • ()小括号:将一个或多个字符捆绑在一起,当作一个整体进行处理.
    • 小括号功能之一是分组过滤被括起来的内容,括号内的内容表示一个整体
    • 括号()内的内容可以被后面的”\n”正则引用,n为数字,表示引用第几个括号的内容。
      • \1:表示从左侧起,第一个括号中的模式所匹配到的字符
      • \2:从左侧期,第二个括号中的模式所匹配到的字符
  • 1.找出包含good和glad的行

    1. [root@MiWiFi-R3-srv ~]# grep -i -E "g(oo|la)d" luffy.txt
    2. good
    3. glad
  • 2、分组之后向前引用

  • {n,m}匹配次数:重复前一个字符各种次数,可以通过-o参数显示明确的匹配过程

5、sed :Stream Editor(字符流编辑器),简称流编辑器。

  • sed 是操作、过滤和转换文本内容的强大工具。常用功能包括结合正则表达式对文件实现快速增删改查,其中查询的功能中最常用的两大功能是过滤(过滤指定字符串)、取行(取出指定行)。
  • 语法 :

    1. sed [选项] [sed内置命令字符] [输入文件]

    | 参数选项 | 功能 | | —- | —- | | -n | 取消默认sed的输出,常与sed内置命令p一起使用 | | -i | 直接将修改结果写入文件, 不要-i,sed 修改的是内存数据 | | -e | 多次编辑,不需要管道符 | | -r | 支持正则扩展 |

    • 内置命令字符
sed的内置命令字符 解释
a append,对文本追加,在指定行后面添加一行/多行文本
d Delete,删除匹配行
i insert,表示插入文本,在指定行前添加一行/多行文本
p Print ,打印匹配行的内容,通常p与-n一起用
s/正则/替换内容/g 匹配正则内容,然后替换内容(支持正则),结尾g代表全局匹配
  • sed匹配范围
范围 解释
空地址 全文处理
单地址 指定文件某一行
/pattern/ 被模式匹配到的每一行
范围区间 10,20 十到二十行
10,+5第10行向下5行
/pattern1/,/pattern2/
步长 1~2,表示1、3、5、7、9行
2~2两个步长,表示2、4、6、8、10、偶数行
  • Sed 实操
    • 文件准备
  1. [root@MiWiFi-R3-srv data]# cat -n luffycity.txt
  2. 1 My name is chaoge.
  3. 2 I teach linux.
  4. 3 I like play computer game.
  5. 4 My qq is 877348180.
  6. 5 My website is http://pythonav.cn.
  • 1、输出文件第2、3行的内容

    1. [root@MiWiFi-R3-srv data]# sed -n '2,3p' luffycity.txt #-n:取消默认输出(默认,sed会输出全部内容)
    2. I teach linux.
    3. I like play computer game.
    1. [root@MiWiFi-R3-srv data]# sed '2,3p' luffycity.txt # 不带 -n 会全部输出文件内容
    2. My name is chaoge.
    3. I teach linux.
    4. I teach linux.
    5. I like play computer game.
    6. I like play computer game.
    7. My qq is 877348180.
    8. My website is http://pythonav.cn.
  • 2、过滤出含有linux的字符串行

    1. [root@MiWiFi-R3-srv data]# sed -n '/linux/p' luffycity.txt
    2. I teach linux.
  • 3、删除含有game的行

    1. #仅删除内存中的数据,源文件内容不变
    2. [root@MiWiFi-R3-srv data]# sed '/game/d' luffycity.txt
    3. My name is chaoge.
    4. I teach linux.
    5. My qq is 877348180.
    6. My website is http://pythonav.cn.
    1. #在源文件中删除数据 需要添加参数 -i
    2. [root@MiWiFi-R3-srv data]# sed '/game/d' luffycity.txt -i
    3. [root@MiWiFi-R3-srv data]# cat luffycity.txt
    4. My name is chaoge.
    5. I teach linux.
    6. My qq is 877348180.
    7. My website is http://pythonav.cn.
  • 4、删除2、3行

    1. [root@MiWiFi-R3-srv data]# sed '2,3d' luffycity.txt -i
    2. [root@MiWiFi-R3-srv data]# cat luffycity.txt
    3. My name is chaoge.
    4. My website is http://pythonav.cn.
  • 5、 删除从第5行往后的内容

    1. [root@MiWiFi-R3-srv data]# sed '5,$d' -i luffycity.txt
    2. [root@MiWiFi-R3-srv data]# cat luffycity.txt -n
    3. 1 My name is chaoge.
    4. 2 My website is http://pythonav.cn.
    5. 3 I love Linux
    6. 4 I love Linux
  • 6、将文件中的My 全部替换成His

    1. #s内置符配合g,代表全局替换,中间的"/"可以替换为"#@/"等
    2. [root@MiWiFi-R3-srv data]# sed 's/My/His/g' -i luffycity.txt
    3. [root@MiWiFi-R3-srv data]# cat luffycity.txt -n
    4. 1 His name is chaoge.
    5. 2 His website is http://pythonav.cn.
    6. 3 I love Linux
    7. 4 I love Linux
  • 7、替换所有His替换为My,同时换掉QQ号为8888888

    1. # 批量替换 需要用 -e参数
    2. [root@MiWiFi-R3-srv data]# sed -e 's/His/My/g' -e 's/877348180/888888/g' luffycity.txt -i
    3. [root@MiWiFi-R3-srv data]# cat luffycity.txt
    4. My name is chaoge.
    5. My website is http://pythonav.cn.
    6. I love Linux
    7. I love Linux
    8. My qq is 888888.
  • 8、在文件第二行追加内容 “I am Learning linux”

    1. # a为在行尾追加,a前面加行号,a后面用空格与追加内容隔开,添加多行信息,用换行符"\n"
    2. [root@MiWiFi-R3-srv data]# sed '2a I am Learning linux' luffycity.txt -i
    3. [root@MiWiFi-R3-srv data]# cat luffycity.txt
    4. My name is chaoge.
    5. My website is http://pythonav.cn.
    6. I am Learning linux
    7. I love Linux
    8. I love Linux
    9. My qq is 888888.
  • 9、在每一行下面插入新内容
    ```

    a 前面不加行号表示每行后面都追加内容

    [root@MiWiFi-R3-srv data]# sed ‘a —————————-‘ luffycity.txt -i [root@MiWiFi-R3-srv data]# cat luffycity.txt My name is chaoge.


My website is http://pythonav.cn.

I am Learning linux

I love Linux

I love Linux

My qq is 888888.

  1. - 10、在第二行上面插入内容“i am 27

i为在行前面追加内容,用法与a相同

[root@MiWiFi-R3-srv data]# sed ‘2i I am 27’ luffycity.txt -i [root@MiWiFi-R3-srv data]# cat luffycity.txt My name is chaoge.

I am 27

My website is http://pythonav.cn.

I am Learning linux

I love Linux

I love Linux

My qq is 888888.

  1. <a name="3127dd92"></a>
  2. ### 7、awk:是一个强大的linux命令,有强大的文本格式化的能力,支持条件判断、数组、循环等功能
  3. <a name="fa1a1b35"></a>
  4. #### 7.1 awk基础语法

awk [option] ‘pattern[action]’ file … awk 参数 ‘条件动作’ 文件

  1. - `Action`指的是动作,awk擅长文本格式化,且输出格式化后的结果,因此最常用的动作就是`print``printf`
  2. - `awk` 提取数据最外层用单引号包裹花括号`'{}'`,在花括号内部使用 `print``printf`
  3. - `awk` 花括号内部输入的文本信息用双引号`""`包裹。
  4. - `awk`是按行处理文件,一行处理完毕,处理下一行,根据用户指定的分割符去工作,没有指定则默认空格
  5. - `awk`默认以空格为分隔符,且多个空格也识别为一个空格,作为分隔符
  6. - 指定了分隔符后,`awk`把每一行切割后的数据对应到内置变量`$0``$1`......`$NF-1``$NF`.
  7. - `$0` :完整的数据输入
  8. - `$NF`:为最后一列
  9. - `$n`: n为正整数 表示分割后的第n个字段
  10. - `FN`:字段分割符 默认为空格
  11. - `NR`: 当前记录的行数
  12. <a name="6d30cea0"></a>
  13. ##### 7.1.1 awk参数
  14. | 参数 | 用途 |
  15. | --- | --- |
  16. | -F | 指定分割字段符 |
  17. | -v | 定义或修改一个awk内部的变量 |
  18. | -f | 从脚本文件中读取awk命令 |
  19. - 使用案例
  20. - 测试文件准备

[root@localhost ~]# cat pwd.txt -n # 文件实际25行,只复制前五行 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

  1. - 1、显示文件第五行

[root@localhost ~]# awk ‘NR==5’ pwd.txt lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

  1. - 注意一个等于号,是修改变量值的意思,两个等于号是关系运算符,是"等于"的意思
  2. - 2、显示文件2-5

[root@localhost ~]# awk ‘NR==2,NR==5’ pwd.txt bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

  1. - 3、给每一行的内容添加行号

[root@localhost ~]# awk ‘{print NR,$0}’ pwd.txt 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

  1. - 4、显示文件3-5行且输出行号

[root@localhost ~]# awk ‘NR==3,NR==5 {print NR,$0}’ pwd.txt 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

  1. - 5、显示pwd.txt文件的第一列,倒数第二和最后一列

[root@localhost ~]# awk -F ‘:’ ‘{print $1,$(NF-1),$NF}’ pwd.txt root /root /bin/bash bin /bin /sbin/nologin daemon /sbin /sbin/nologin adm /var/adm /sbin/nologin

  1. - awk使用案例2
  2. - 测试数据准备

[root@localhost ~]# cat awk_test.txt lex1 alex2 alex3 alex4 alex5 alex6 alex7 alex8 alex9 alex10 alex11 alex12 alex13 alex14 alex15 alex16 alex17 alex18 alex19 alex20 alex21 alex22 alex23 alex24 alex25 alex26 alex27 alex28 alex29 alex30 alex31 alex32 alex33 alex34 alex35 alex36 alex37 alex38 alex39 alex40 alex41 alex42 alex43 alex44 alex45 alex46 alex47 alex48 alex49 alex50

  1. - 一次性输出多列

[root@localhost ~]# awk ‘{print $1,$2}’ awk_test.txt lex1 alex2 alex6 alex7 alex11 alex12 alex16 alex17 alex21 alex22 alex26 alex27 alex31 alex32 alex36 alex37 alex41 alex42 alex46 alex47

  1. - 自定义输出内容:内置变量`$1、$2`都不得添加双引号,否则会识别为文本,尽量别加引号

[root@localhost ~]# awk ‘{print “第一列”, $1,”第二列”,$2}’ awk_test.txt 第一列 lex1 第二列 alex2 第一列 alex6 第二列 alex7 第一列 alex11 第二列 alex12 第一列 alex16 第二列 alex17 第一列 alex21 第二列 alex22 第一列 alex26 第二列 alex27 第一列 alex31 第二列 alex32 第一列 alex36 第二列 alex37 第一列 alex41 第二列 alex42 第一列 alex46 第二列 alex47

  1. - 输出整行信息

[root@localhost ~]# awk ‘{print}’ awk_test.txt #或者使用awk ‘{print $0}’ awk_test.txt lex1 alex2 alex3 alex4 alex5 alex6 alex7 alex8 alex9 alex10 alex11 alex12 alex13 alex14 alex15 alex16 alex17 alex18 alex19 alex20 alex21 alex22 alex23 alex24 alex25 alex26 alex27 alex28 alex29 alex30 alex31 alex32 alex33 alex34 alex35 alex36 alex37 alex38 alex39 alex40 alex41 alex42 alex43 alex44 alex45 alex46 alex47 alex48 alex49 alex50

  1. <a name="58b62a13"></a>
  2. ##### 7.1.2 awk 分隔符
  3. - 输入分隔符:`FS` 即 `field separator`
  4. - `awk`逐行处理文本的时候,以输入分割符为准,把文本切成多个片段,默认符号是空格.<br />当我们处理特殊文件,没有空格的时候,可以通过 -F 参数自由指定分隔符,分隔符需要用单引号`''`包裹。
  5. - 除了使用`-F`选项,还可以使用变量的形式,指定分隔符,使用`-v`选项搭配,修改`FS`变量

[root@localhost ~]# awk -v ‘FS=:’ ‘{print $1,$(NF-1),$NF}’ pwd.txt root /root /bin/bash bin /bin /sbin/nologin daemon /sbin /sbin/nologin adm /var/adm /sbin/nologin

  1. - 输出分割符:`PFS` `output field separator`
  2. - `awk`执行完命令,默认用空格隔开每一列,这个空格就是`awk`的默认输出符
  3. - 通过`OFS`设置输出分割符,记住修改变量必须搭配选项`-v`

[root@localhost ~]# awk -v FS=’:’ -v OFS=’——‘ ‘NR==2 {print $1,$2}’ pwd.txt bin——x

  1. - 输出分隔符与`逗号`,`awk`是否存在输出分隔符,特点在于`{print $1,$3 }``$1``$3`之间是否存有`,```{print $1,$3 }`默认有输出分隔符,`{print $1$3 }`默认无输出分隔符。
  2. <a name="4b80c767"></a>
  3. ##### 7.1.3 awk 变量
  4. - 内置变量
  5. | 变量名称 | 变量意义 |
  6. | --- | --- |
  7. | FS | 输入字段分隔符, 默认为空白字符 |
  8. | OFS | 输出字段分隔符, 默认为空白字符 |
  9. | RS | 输入记录分隔符(输入换行符), 指定输入时的换行符 |
  10. | ORS | 输出记录分隔符(输出换行符),输出时用指定符号代替换行符 |
  11. | NF | NF:number of Field,当前行的字段的个数(即当前行被分割成了几列),字段数量 |
  12. | NR | NR:行号,当前处理的文本行的行号。 |
  13. | FNR | FNR:各文件分别计数的行号 |
  14. | FILENAME | FILENAME:当前文件名 |
  15. | ARGC | ARGC:命令行参数的个数 |
  16. | ARGV | ARGV:数组,保存的是命令行所给定的各参数 |
  17. | - 内置变量应用 | |
  • NR,NF、FNR

  • 输出每行行号,以及字段总个数

    1. [root@MiWiFi-R3-srv ~]# awk -F ':' '{print NF,NR}' pwd.txt
    2. 7 1
    3. 7 2
    4. 7 3
    5. 7 4
    6. 7 5
    7. #NF 是指分隔后的每行被分隔成的字段数, NR 是指行号
    1. [root@MiWiFi-R3-srv ~]# awk -F ':' '{print NR}' pwd.txt luffy.txt
    2. #NR将两个文件的行数合道一起打印。
    3. [root@MiWiFi-R3-srv ~]# awk -F ':' '{print FNR}' pwd.txt luffy.txt
    4. #FNR 会分别打印两个文件的行号。
  • 输出每行行号,以及指定的列

    1. [root@MiWiFi-R3-srv ~]# awk -F ':' -v OFS='---' '{print NR,$1,$2,$5}' pwd.txt
    2. 1---root---x---root
    3. 2---bin---x---bin
    4. 3---daemon---x---daemon
    5. 4---adm---x---adm
    6. 5---lp---x---lp
    7. 6---sync---x---sync
  • RS:修改输入分隔符,默认为回车键,通过-v RS=' '将默认输入分隔符变为空格,这样操作的结果就是遇到空格进行换行处理。

  • ORS:修改输出分隔符, ```

  • 自定义变量

    • 自定义变量 :自己定义的变量

      • 自定义变量方式

        • 方式一: -v varName=value
        • 方法二: 在程序中直接定义。

          1. [root@pylinux tmp]# awk 'BEGIN{chaogeVar="超哥带你学linux,还怕学不会咋的";chaogeVar2="学的会,必须学得会" ;print chaogeVar,chaogeVar2}'
        • 方法三: 间接引用shell变量

          1. [root@pylinux tmp]# studyLinux="超哥讲的linux是真滴好,嘿嘿"
          2. [root@pylinux tmp]#
          3. [root@pylinux tmp]#
          4. [root@pylinux tmp]# awk -v myVar=$studyLinux 'BEGIN{print myVar}' # -v是给awk定义变量
          5. 超哥讲的linux是真滴好,嘿嘿

7.1.4 awk 格式化
  • printf格式化输出

    • Printf需要指定format.format用于指定后面的每个item的输出格式;
    • format格式的指示符都以%开头,后跟一个字符;如下:

      1. %c: 显示字符的ASCII码;
      2. %d, %i:十进制整数;
      3. %e, %E:科学计数法显示数值;
      4. %f: 显示浮点数;
      5. %g, %G: 以科学计数法的格式或浮点数的格式显示数值;
      6. %s: 显示字符串;
      7. %u: 无符号整数;
      8. %%: 显示%自身;
    • printf修饰符:

      1. -: 左对齐;默认右对齐,
      2. +:显示数值符号; printf "%+d"
    • Printf打印内容不会自动换行,需要添加换行符\n

    • 使用printf动作,'{printf "%s\n",$1}',替换的格式和变量之间得有逗号,,且替换内容与格式数量要保持一致。
    • 补充 awk后面不跟文件时需要在打印的参数前面加BEGIN格式如下:
      1. awk 'BEGIN{printf "%d\n%d\n%d\n%d\n%d\n",1,2,3,4,5}'#BEGIN位置在单引号内花括号外。

7.1.5 awk 模式pattern
  • awk的特殊模式patternBEGINEND

    • BEGIN:就是AWK处理文本前,先执行BEGIN模式指定的动作

      1. [root@MiWiFi-R3-srv ~]# awk -F ':' -v OFS='|' 'BEGIN{print "Linux学习"}{print $1,$2,$4}' pwd.txt
      2. Linux学习
      3. root|x|0
      4. bin|x|1
      5. daemon|x|2
      6. adm|x|4
      7. lp|x|7
      8. sync|x|0
    • END:AWK处理完所有指定的文本后,需要执行的动作

      1. [root@localhost ~]# awk -F ':' -v OFS='--' 'END{print "helloworld"}{print NR,$1,$2}' pwd.txt
      2. 1--root--x
      3. 2--bin--x
      4. 3--daemon--x
      5. 4--adm--x
      6. 5--lp--x
      7. 6--sync--x
      8. .......
      9. 89--gnome-initial-setup--x
      10. 90--sshd--x
      11. 91--tcpdump--x
      12. 92--yanguiqiang--x
      13. helloworld
  • 关系运算符模式

    | 关系运算符 | 解释 | 示例 | | —- | —- | —- | | < | 小于 | x= | 大于等于 | x>=y | | > | 大于 | x>y | | ~ | 匹配正则 | x~/正则/ | | !~ | 不匹配正则 | x!~/正则/ |

    • 关系运算符模式,awk默认执行打印输出动作
      1. [root@localhost ~]# awk 'NR>2 {print $1}' t.txt
      2. myLinux11
  • AWK 空模式:未指定模式,因此每一行都执行了对应的动作,空模式会匹配文档的每一行

    1. [root@localhost ~]# awk '{print $1}' t.txt
    2. myLinux1
    3. myLinux6
    4. myLinux11
  • awk默认是按行处理文本,如果不指定任何模式(条件),awk默认一行行处理如果指定了模式,只有符合模式的才会被处理

    1. [root@localhost ~]# cat -n t.txt
    2. 1 myLinux1 myLinux2 myLinux3 myLinux4 myLinux5
    3. 2 myLinux6 myLinux7 myLinux8 myLinux9 myLinux10
    4. 3 myLinux11 myLinux12 myLinux13 myLinux14 myLinux15 myLinux16 myLinux17 myLinux18
    5. [root@localhost ~]# awk 'NF==5 {print $1}' t.txt
    6. myLinux1
    7. myLinux6
    8. [root@localhost ~]# awk 'NF==8 {print $1}' t.txt
    9. myLinux11

7.1.6 AWK 与正则表达式
  • 正则表达式主要与awk的pattern模式(条件)结合使用,只有被模式匹配到的、符合条件的行才会执行动作
  • awk命令使用正则表达式,必须把正则放入 “//“ 双斜杠中,匹配到结果后执行动作{print $0},打印整行信息

    • 找出pwd.txt中有以games开头的行

      1. [root@localhost ~]# awk '/^games/{print $0}' pwd.txt
      2. games:x:12:100:games:/usr/games:/sbin/nologin
      3. games:x:12:100:games:/usr/games:/sbin/nologin
    • 找出pwd.txt文件中禁止登录的用户(/sbin/nologin)

      1. [root@localhost ~]# awk '/\/sbin\/nologin/{print $0}' pwd.txt
      2. bin:x:1:1:bin:/bin:/sbin/nologin
      3. daemon:x:2:2:daemon:/sbin:/sbin/nologin
      4. adm:x:3:4:adm:/var/adm:/sbin/nologin
      5. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
      6. mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
      7. operator:x:11:0:operator:/root:/sbin/nologin
      8. games:x:12:100:games:/usr/games:/sbin/nologin
    • 找出mail用户到nobody用户之间的内容

      1. [root@localhost ~]# awk '/^mail/,/^nobody/{print $0}' pwd.txt
      2. mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
      3. operator:x:11:0:operator:/root:/sbin/nologin
      4. games:x:12:100:games:/usr/games:/sbin/nologin
      5. ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
      6. nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
    • 找出第4-8行的信息

      [root@localhost ~]#  awk 'NR>=4 && NR<=8{print NR,$0}' pwd.txt
      4 adm:x:3:4:adm:/var/adm:/sbin/nologin
      5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
      6 sync:x:5:0:sync:/sbin:/bin/sync
      7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
      8 halt:x:7:0:halt:/sbin:/sbin/halt
      

8、总结

对比 grep sed awk
作用 文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,打印匹配到的行 操作、过滤和转换文本内容,包括结合正则表达式对文件实现快速增删改查,其中查询的功能中最常用的两大功能是过滤(过滤指定字符串)、取行(取出指定行) 有强大的文本格式化的能力,支持条件判断、数组、循环等功能
语法 grep [options] [pattern] file sed [选项] [sed内置命令字符] [输入文件] awk [option] 'pattern[action]' file ...
范例 grep -i "root" pwd.txt -n #不区分大小写,显示匹配到的内容与行号 sed -n '/linux/p' luffycity.txt awk '{print NR,$0}' pwd.txt
与正则表达式的结合 正则表达式放在引号内 s/正则/替换内容/g 正则表达式主要与awk的pattern模式(条件)
结合使用,只有被模式匹配到的、符合条件的行才会执行动作 awk命令使用正则表达式,必须把正则放入 “//“ 双斜杠中,匹配到结果后执行动作{print $0},打印整行信息