linux那些事儿-文本三剑客

  1. linux那些事儿-文本三剑客
    1. 正则表达式
    2. 文本三剑客之grep
    3. 文本三剑客之sed
    4. 文本三剑客之awk
    5. 总结

linux那些事儿-文本三剑客

对于接触过Linux操作系统的人来说,应该都听过awk、grep、sed,它们是Linux下文本处理的三大利器,合称文本三剑客,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。grep更适合单纯的查找或匹配文本,sed更适合编辑匹配到的文本,awk更适合格式化文本,对文本进行较复杂格式处理。文本三剑客均支持正则表达式,因此,在学习文本三剑客之前我们需要先来了解一下正则表达式。

正则表达式

又称规则表达式,是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开来的。

正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。

元字符 描述
\ 转义符
^ ^word:搜索以word开头的内容
$ word$:搜索以word结尾的内容
^$ 空行
* 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* 任意长度的任意字符,不包括0次
.点 匹配除“\n”和”\r”之外的任何单个字符
| 或运算,可匹配多个条件

文本三剑客之grep

grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

grep家族包括grep、egrep和fgrep。其中egrep是grep的扩展,支持更多的re元字符,fgrep则是fixed grep或fast grep。

  • 用法

    grep [选项] pattern file

    其中:pattern代表被查找的字符,可以插入对应的元字符

  • 选项

    -c:只输出匹配行的计数。 
    -i:不区分大小写。
    -h:查询多文件时不显示文件名。
    -l:查询多文件时只输出包含匹配字符的文件名。
    -n:显示匹配行及行号。
    -s:不显示不存在或无匹配文本的错误信息。
    -v:显示不包含匹配文本的所有行。
    --color=auto :可以将找到的关键词部分加上颜色
    -A:显示匹配的内容及其后n行
    -B:显示匹配的内容及其前n行
  • 例如

    [root@demo ~]# grep "cdrom" file 
    cdrom
    [root@demo ~]# grep -i "cdrom" file
    # Use CDROM installation media
    cdrom
    [root@demo ~]# grep -i -B2 -c "cdrom" file
    2
    [root@demo ~]# grep -i --color=none "cdrom" file
    # Use CDROM installation media
    cdrom
    [root@demo ~]# grep -i -A1 "cdrom" file
    # Use CDROM installation media
    cdrom
    # Keyboard layouts
    [root@demo ~]# grep -i -B2 "cdrom" file
    # Use graphical install
    graphical
    # Use CDROM installation media
    cdrom
    [root@demo ~]# grep -i -B2 -n "cdrom" file
    9-# Use graphical install
    10-graphical
    11:# Use CDROM installation media
    12:cdrom

文本三剑客之sed

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下一行,执行下一个循环。如果没有使用诸如“D”的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非使用重定向存储输出或-i。

  • 用法

    sed [选项] pattern file

    其中,pattern部分涵盖被处理行的地址定界,以及对行的处理,如替换等

  • 选项

    -n:取消模式空间输出,转而输出匹配到的行,需要地址定界,通常组合编辑命令p进行打印输出。
    -e:多个命令在处理文件时,将多个命令中指定的命令添加到运行的命令中。
    -f:在处理文件时,将特定文件中指定的内容添加到运行的命令中,使文件做相应的修改。
    -i:直接将处理的结果写入文件
  • 编辑

      p:打印当前模式空间内容,追加到默认输出之后
      a:在指定行后面追加文本,支持使用\n实现多行追加
      i:在行前面插入文本,支持使用\n实现多行追加
      c:替换行为单行或多行文本,支持使用\n实现多行追加
      w:保存模式匹配的行至指定文件
      r:读取指定文件的文本至模式空间中匹配到的行后
      s///:查找替换,支持使用其它分隔符,如:s@@@,s###等,加g表示行内全局替换;
    
  • 例如

    [root@demo ~]# head -5 file 
    #version=RHEL8
    ignoredisk --only-use=nvme0n1
    autopart --type=lvm
    # Partition clearing information
    clearpart --none --initlabel
    [root@demo ~]# sed -n '1p' file #p打印,1为行号,即为打印第一行
    #version=RHEL8
    [root@demo ~]# sed -n '1,5p' file #打印1-5行
    #version=RHEL8
    ignoredisk --only-use=nvme0n1
    autopart --type=lvm
    # Partition clearing information
    clearpart --none --initlabel
    [root@demo ~]# sed -n '1~2p' file #打印1行及后续步进为2的所有行,也就是奇数行打印。
    #version=RHEL8
    autopart --type=lvm
    clearpart --none --initlabel
    fod
    # Use graphical install
    # Use CDROM installation media
    [root@demo ~]# sed '2a123' file #第二行后加入123
    #version=RHEL8
    ignoredisk --only-use=nvme0n1
    123
    [root@demo ~]# sed '1i123' file #第一行前加入123
    123
    #version=RHEL8
    [root@demo ~]# sed -i '1i123' file #-i对原文件生效
    [root@demo ~]# head -3 file
    123
    #version=RHEL8
    ignoredisk --only-use=nvme0n1
    [root@demo ~]# sed -e '1i123' -e '2a455' file #-e同时输入多个指令,在原第一行前加入123,在原第二行后边加入456
    123
    123
    #version=RHEL8
    455
    [root@demo ~]# sed '2s/RHEL/rhel/' file #第2行RHEL替换为rhel
    123
    #version=rhel8
    ignoredisk --only-use=nvme0n1
    [root@demo ~]# cat txt
    s/RHEL/rhel/g
    [root@demo ~]# sed -f txt file #利用txt文件中的命令,完成全文的查找替换
    123
    #version=rhel8
    ignoredisk --only-use=nvme0n1
    autopart --type=lvm
    [root@demo ~]# sed '1rtxt' file #将txt文件中的内容读到第一行后
    123
    s/RHEL/rhel/g
    #version=RHEL8

文本三剑客之awk

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理,它更像是一门编程语言,支持条件判断、数组、循环等功能。

  • 用法

    awk [选项] pattern file

    其中pattern主要包含两部分,匹配规则和执行命令,而awk最擅长的就是文本的格式化处理,所以最常见的动作就是print。

  • 选项

    -F:指定分隔符,awk命令默认分隔符为空格或制表符
    -v:定义或者修改一个变量
    -f:从脚本文件中读取awk命令
  • 内置变量

    ARGC:命令行参数个数
    ARGV:命令行参数排列
    ENVIRON:支持队列中系统环境变量的使用
    FILENAME:awk浏览的文件名
    FNR:浏览文件的记录数
    FS:设置输入字符分隔符,等价于命令行 -F选项
    OFS:输出字符分隔符
    NF:浏览记录的域的个数(几列)
    NR:已读的记录数(几行)
    ORS:输出记录分隔符
    RS:输入记录分隔符
    $0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。
  • 例如

    [root@demo ~]# cat file                 #分隔符为空格
    hello linux hah
    hello file
    file process
    [root@demo ~]# awk '{print $1}' file #打印file文件的第一列
    hello
    hello
    file
    [root@demo ~]# awk '{print $1,$2}' file #打印第一列和第二列
    hello linux
    hello file
    file process
    [root@demo ~]# awk -v "OFS=:" '{print $1,$2}' file #将输出字符分隔符替换为:
    hello:linux
    hello:file
    file:process
    [root@demo ~]# awk -F: '{print $1}' /etc/passwd #设置输入字符分隔符为:
    root
    bin
    daemon
    adm
    lp
    [root@demo ~]# awk '{print NR}' file #打印已读记录数
    1
    2
    3
    [root@demo ~]# awk '{print NF}' file #打印每个记录中列数
    3
    2
    2
    [root@demo ~]# awk '{print $(NF-1)}' file #打印倒数第二列
    linux
    hello
    file

总结

三剑客各有应用场景,其中grep主要用于搜索字符串,sed主要用于文本的处理,而awk主要用于文本处理的格式化。

grep主要以行为单位处理,sed和awk逐行读取文件,以字段为单位处理文本。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1096485692@qq.com