当前位置 博文首页 > 测试开发小记:Linux三剑客grep、awk和sed

    测试开发小记:Linux三剑客grep、awk和sed

    作者:测试开发小记 时间:2021-01-19 20:03

    grep,sed 和 awk是Linux/Unix 系统中常用的三个文本处理的命令行工具,称为文本处理三剑客。本文将简要介绍这三个命令并给出基本用法。

    管道

    在介绍这两个命令之前,有必要介绍一下Unix/Linux中管道(pipe)的概念。管道将一个命令/程序/进程的输出发送到另一个命令/程序/进程,以进行进一步处理。是一种进程间通信机制,使用管道符"|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。

    管道实现了数据在多个命令之间传递,不需要创建临时文件来传递,它是单向的,数据通过管道从左向右流动。

    实例1:
    cat test.txt | grep test1

    # cat test.txt | grep test1
    test1
    test111
    test3 test1
    test111
    # cat test.txt | grep test1 | grep test3
    test3 test1
    #
    

    实例2:

    # cat test.txt | head -3
    test1
    test2
    test3
    # cat test.txt | tail -5
    test
    test
    
    test
    rrrr
    # 
    

    grep

    定义

    grep(Global Regular Expression Print) 命令用于搜索文件的特定模式,它不能增加、修改、删除文本内容,通常用于搜索过滤文本,显示被模式匹配到的行。使用正则表达式进行文本匹配(正则表达式参考文章《Python正则表达式》),它的使用权限是所有用户。

    命令形式:
    grep [OPTIONS] PATTERN [FILE...]
    扩展正则表达式(rgrep)添加 -E 参数:
    grep -E [OPTIONS] PATTERN [FILE...]

    选项参数

    • -v 或 --invert-match : 显示不被 pattern匹配到的行
    • -n 或 --line-number : 显示匹配的行号
    • -o 或 --only-matching :仅显示匹配到的字符串
    • -c 或 --count : 统计匹配的行数
    • -i 或 --ignore-case :忽略字符大小写
    • -m或--max-count:-m 1 ,匹配到1行后停止匹配
    • -A<显示行数> 或 --after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行之后的内容。
    • -B<显示行数> 或 --before-context=<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前的内容。

    实例1:查找文件内容,显示行号

    查找文件内容包含'test1'的行,显示行数

    # grep -n test1 test.txt 
    1:test1
    7:test111
    9:test3 test1
    11:test111
    # grep -o test1 test.txt  
    test1
    test1
    test1
    test1
    # grep -no test1 test.txt
    1:test1
    7:test1
    9:test1
    11:test1
    

    实例2:查找文件内容,不包含test1的行

    # grep -nv test1 test.txt
    2:test2
    3:test3
    4:test4
    5:test5
    6:test6
    8:test2
    10:test
    

    实例3:grep 正则表达式

    查找test1开头的行

    # grep -n ^test1 test.txt
    1:test1
    7:test111
    11:test111
    

    查找以1结尾的行

    # grep -n 1$ test.txt    
    1:test1
    7:test111
    9:test3 test1
    11:test111
    

    查看进程

    # ps -aux | grep chrome
    root       5425  0.4  1.8 869280 34200 pts/0    Sl   Dec22  11:31 /opt/google/chrome/chrome --no-sandbox
    root       5439  0.0  0.0 563592  1132 pts/0    S    Dec22   0:00 /opt/google/chrome/chrome --type=zygote --no-zygote-sandbox --no-sandbox
    root       5440  0.0  0.1 563592  2836 pts/0    S    Dec22   0:06 /opt/google/chrome/chrome --type=zygote --no-sandbox
    root       5441  0.0  0.0  26452   208 pts/0    S    Dec22   0:00 /opt/google/chrome/nacl_helper --no-sandbox
    root       5442  0.0  0.0  26452   144 pts/0    S    Dec22   0:00 /opt/google/chrome/nacl_helper --no-sandbox
    

    sed

    定义

    sed(Stream Editor)是一种流编辑器,一次处理一行内容,将行存储在模式空间(临时缓冲区),然后用sed命令处理模式空间中的内容,处理完成后将内容送入屏幕,然后清除模式空间,继续读入下一行,执行下一个循环,直到文件末尾。这个过程中不会改变文件内容(除了 -i 选项)。

    命令形式:
    sed [选项] [sed命令] [-f <script FILE>] [FILE]
    查看帮助文档:

    man sed
    sed -h
    

    选项

    • -h: 显示帮助信息
    • -n: 仅显示 script处理后的结果,常与sed命令p连用:sed -n 'p' test.txt 打印test.txt文件内容
    • -e:直接在指令列模式上进行 sed 的动作编辑,不修改原文件,输出到终端
    • -i:修改文件内容,而不输出到终端
    • -f filename : sed 动作写在filename 内,执行 filename 内的sed 动作
    • -r∶扩展正规表达式

    常用命令

    • a:append,新增: sed -e '4 a newline' test.txt
    • c:change,取代: sed -e '2,5c No 2-5 number' test.txt
    • d:delete,删除: sed -e '2,5d' test.txt
      • sed '/^$/d' test.txt:删除test.txt文件空行
    • i:insert,插入: sed -e '2i newline' test.txt
    • p:print,打印:sed -n 'p' test.txt
    • s:substitute,替换: sed -e 's/old/new/g' test.txt
      • sed 's/$/%/' test.txt:在每行末尾添加%
      • sed s/ *//g test.txt: 删除test.txt文件空格
    • N:将下一行添加到pattern space中,将当前读入行和用N命令添加的下一行看成“一行”

    注意在替换操作中,替换时用的分割符 '/' 可以使用其它符号代替,特别是替换的内容中有 '/' 时,可以使用@、#、%等符号代替。

    实例1:打印并输出数据

    打印并输出第5行数据

    # sed -n '5p' test.txt
    test5
    # cat -n test.txt | sed -n '5p' 
         5	test5
    # 
    

    打印并输出第3-5行数据

    # sed -n '3,5p' test.txt
    test3
    test4
    test5
    

    取反,不选择第3到5行数据

    # sed -n '3,5!p' test.txt
    test1
    test2
    

    隔行输出

    # sed -n '1~2p' test.txt
    test1
    test3
    test5
    # sed -n '1~3p' test.txt
    test1
    test4
    # 
    

    实例2:将匹配的行数据输出到指定文件

    # 累加
    sed -n '1~2p' test.txt >> a.log
    # 覆盖
    sed -n '1~3p' test.txt > a.log 
    
    # sed -n '1~2p' test.txt>> a.log
    # cat a.log
    test1
    test3
    test5
    # sed -n '1~3p' test.txt > a.log 
    # cat a.log
    test1
    test4
    # 
    

    实例3:新增、插入字符串

    在第2行后加上 newLine

    # sed '2 a newline' test.txt
    test1
    test2
    newline
    test3
    test4
    test5
    # 
    

    在第2行前加上 newline

    # sed '2 i newline' test.txt
    test1
    newline
    test2
    test3
    test4
    test5
    

    实例4:全局替换

    将所有的test2替换为test222

    # sed -e 's/test2/test222/g' test.txt
    test1
    test222
    test3
    test4
    test5
    # sed -e 's/test2/test222/' test.txt
    test1
    test222
    test3
    test4
    test5
    

    实例5:修改文件

    前面的新增、替换操作都没有改变文件内容,如果要使文件修改生效,需要使用 -i 选项。

    # sed -i 's/test2/test222/' test.txt
    # cat test.txt 
    test1
    test222
    test3
    test4
    test5
    # 
    

    awk

    定义

    awk是一种文本模式扫描和处理的编程语言,由 Aho, Weinberger 和 Kernighan开发。awk功能强大,可用于数据提取和统计,常用在shell脚本中。awk逐行读入文件,以空格为默认分隔符将每行切片,切开的部分再进行后续处理。

    命令形式:
    awk [options] 'pattern action' [FILE(s)]

    • pattern:正则表达式
    • action:对匹配到的内容执行的命令(默认为输出每行内容)

    常用参数

    • $0: 整条记录(当前行)
    • $1 - $n: 表示当前行的第n个域
    • FILENAME: awk浏览的文件名
    • BEGIN: 处理文本之前要执行的操作
    • END: 处理文本之后要执行的操作
    • FS: 设置输入域分隔符,等价于命令行 -F 选项,默认为空格“ ”
      • awk -F: '{print $1}' test.txt
      • 或者 awk 'BEGIN {FS = ":"} {print $1}' test.txt
    • NF: 浏览记录的域的个数/列数
    • NR: 已读的记录数/行数
    • FNR: 当前输入文件的记录数
    • OFS: 输出域分隔符,默认为空格“ ”
    • ORS: 输出记录分隔符,默认为“\n”
    • RS: 控制记录分隔符
    • exit:匹配到第一行内容后退出:awk -F: '{print $2;exit}' test.txt ,grep使用 -m 参数

    实例1:查找、打印

    搜索/etc/passwd有root关键字的所有行

    # awk -F : '/root/ {print $0}' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    #
    # awk -F : '/root/ {print $7}' /etc/passwd
    /bin/bash
    /sbin/nologin
    

    打印etc/passwd/的第二行信息

    # awk -F : 'NR==2 {print $0}' /etc/passwd
    bin:x:1:1:bin:/bin:/sbin/nologin
    #
    

    实例2:BEGIN、END制表

    使用 begin加入标题

    [root@iZ8vb54310gt89j8qct198Z tmp]# awk -F : 'BEGIN {print "No", "User", "Auth"} {print NR "|" $1 "|" $2} END {print FILENAME}' /etc/passwd
    No User Auth
    1|root|x
    2|bin|x
    3|daemon|x
    4|adm|x
    5|lp|x
    6|sync|x
    7|shutdown|x
    8|halt|x
    9|mail|x
    .................
    28|nscd|x
    29|exim|x
    /etc/passwd
    

    实例3:自定义分割符

    # echo "123|456|789"
    123|456|789
    # echo "123|456|789" | awk 'BEGIN{RS="|"}{print $0}'
    123
    456
    789
    
    --THE END--

    文章标题:Linux三剑客grep、awk和sed
    本文作者:hiyo
    本文链接:https://www.cnblogs.com/hiyong/p/14238392.html
    欢迎关注公众号:「测试开发小记」及时接收最新技术文章!

    下一篇:没有了