【shell笔记>命令】grep,sed,awk

grep

grep的基本用法

grep命令是支持正则表达式的一个多用途文本搜索工具,一般格式为

grep 选项 模式 文件

sed是一个非交互式文本编辑器,它可对文本文件和标准输入进行编辑,标准输入可以是来自键盘输入、文件重定向、字符串、变量,甚至来自管道的文本。sed适用于以下三中场合:

  • 编辑相对交互式文本编辑器而言太大的文件。
  • 编辑命令太复杂,在交互式文本编辑器中难以输入的情况。
  • 对文件扫描一遍,但是需要执行多个编辑函数的情况。
  • sed 只是对缓冲区中原始文件的副本进行编辑,并不编辑原始文件。如果需要保存文件改动的内容,需要将输出重定向到另一个文件。

    调用 sed 有三种方式,一种为Shell命令行方式,另外两种是将 sed 命令写入脚本文件,然后执行该脚本文件。

  • 在Shell命令行输入命令调用 sed ,格式为 sed [选项] 'sed命令' 输入文件
  • sed 命令插入脚本文件后,然后通过 sed 命令调用它,格式为 sed [选项] -f sed 脚本文件 输入文件
  • sed 命令插入脚本文件后,最常用的方法是设置该脚本文件为可以执行,然后直接执行该脚本文件,格式为 ./sed脚本文件 输入文件

    第三种方式脚本文件需要以 sha-bang(#!) 符号开头。无论哪种方式,如果没有指定输入文件, sed 将从标准输入接收输入。常用选项有三个

    It should be mailed to zawu@seu.edu.cn ===================================================== Certificate Subject: /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus The above string is known as your user certificate subject, and t uniquely identifies theis user. $88 To install this user certificate, please save this e-mail message into the following file. /home/alloy/linuxshell/CH02/usercert.pem sed -n : 不打印sed编辑对象的全部内容
    wsx@wsx-ubuntu:~/桌面$ sed -n '1p' input
        This is a Certificate Request file:
    wsx@wsx-ubuntu:~/桌面$ sed '1p' input
        This is a Certificate Request file:
        This is a Certificate Request file:
        It should be mailed to zawu@seu.edu.cn
        =====================================================
        Certificate Subject:
        /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
        The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
        To install this user certificate, please save this e-mail message into the following file.
        /home/alloy/linuxshell/CH02/usercert.pem
    

    利用sed命令打印范围行:

    wsx@wsx-ubuntu:~/桌面$ sed -n '3,6p' input 
        It should be mailed to zawu@seu.edu.cn
        =====================================================
        Certificate Subject:
    sed -e: sed传递多个编辑命令时使用
    
    wsx@wsx-ubuntu:~/桌面$ sed -n '/Certificate/=' input 
    wsx@wsx-ubuntu:~/桌面$ sed -n -e '/Certificate/p' input  -e '/Certificate/=' input
        This is a Certificate Request file:
        Certificate Subject:
    sed -f:调用sed脚本文件时才起作用
    
    wsx@wsx-ubuntu:~/桌面$ sed '/file:/a\We append a new line.' input 
        This is a Certificate Request file:
    We append a new line.
        It should be mailed to zawu@seu.edu.cn
        =====================================================
        Certificate Subject:
        /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
        The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
        To install this user certificate, please save this e-mail message into the following file.
        /home/alloy/linuxshell/CH02/usercert.pem
    

    脚本用法:

    #! /bin/sed -f 
    /file:/a\       #a\表示在此处添加文本
    # 添加文本
    We append a new line.\
    We append a another line.
    

    sed基本编辑命令可以放在单引号内,也可放在单引号外。

    sed文本定位的一组例子

    匹配元字符,用转义符\进行屏蔽

    wsx@wsx-ubuntu:~/桌面$ sed -n '/\./p' input 
     It should be mailed to zawu@seu.edu.cn
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
     /home/alloy/linuxshell/CH02/usercert.pem
    

    !符号,打印不在2-10的行

    wsx@wsx-ubuntu:~/桌面$ sed -n '2,10!p' input 
     This is a Certificate Request file:
     To install this user certificate, please save this e-mail message into the following file.
     /home/alloy/linuxshell/CH02/usercert.pem
    

    使用行号和关键字匹配限定行范围

    wsx@wsx-ubuntu:~/桌面$ sed -n '/seugrid/,$p' input 
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
     /home/alloy/linuxshell/CH02/usercert.pem
    

    sed基本编辑命令的一组例子

    插入文本:运行脚本,以输入文件名作为参数

    #!/bin/sed -f
    /file:/i\             # i\表示此处换行插入文本
    We insert a new line.
    
    #!/bin/sed -f
    /file:/c\             #c\表示此处换行修改文本
    We modify this line      #修改文本内容
    

    删除文本,符号是d,不带\,与其他命令有所区别,非常灵活。下面删除第一行和最后一行。

    wsx@wsx-ubuntu:~/桌面$ sed '1d' input
     It should be mailed to zawu@seu.edu.cn
     =====================================================
     Certificate Subject:
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
     /home/alloy/linuxshell/CH02/usercert.pem
    wsx@wsx-ubuntu:~/桌面$ sed '$d' input
     This is a Certificate Request file:
     It should be mailed to zawu@seu.edu.cn
     =====================================================
     Certificate Subject:
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
    
    sx@wsx-ubuntu:~/桌面$ sed 's/Certificate/CERTIFICATE/' input
     This is a CERTIFICATE Request file:
     It should be mailed to zawu@seu.edu.cn
     =====================================================
     CERTIFICATE Subject:
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
     /home/alloy/linuxshell/CH02/usercert.pem
    wsx@wsx-ubuntu:~/桌面$ sed -n 's/Certificate/CERTIFICATE/p' input
     This is a CERTIFICATE Request file:
     CERTIFICATE Subject:
    

    写入到一个新文件

    wsx@wsx-ubuntu:~/桌面$ sed -n 's/Certificate/CERTIFICATE/pg' input
     This is a CERTIFICATE Request file:
     CERTIFICATE Subject:
    wsx@wsx-ubuntu:~/桌面$ 
    wsx@wsx-ubuntu:~/桌面$ sed -n '1,5 w output' input
    wsx@wsx-ubuntu:~/桌面$ cat output 
     This is a Certificate Request file:
     It should be mailed to zawu@seu.edu.cn
     =====================================================
    
  • 从文件中可读入文本,格式指定地址 r 文件名

  • 退出命令:q

  • 变换命令:sed命令的y表示字符变换(不等长时会报错)

    wsx@wsx-ubuntu:~/桌面$ sed 'y/fmj/FMJ/' input 
     This is a CertiFicate Request File:
     It should be Mailed to zawu@seu.edu.cn
     =====================================================
     CertiFicate SubJect:
     /O=Grid/OU=GlobusTest/OU=siMpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
     The above string is known as your user certiFicate subJect, and t uniquely identiFies theis user. $88
     To install this user certiFicate, please save this e-Mail Message into the Following File.
     /hoMe/alloy/linuxshell/CH02/usercert.peM
    
  • 显示控制字符:控制字符就是非打印字符,如退格键、F1键等。使用sed l命令。

  • 在命令行执行命令组,用{}符号,与-e选项功能类似。

    wsx@wsx-ubuntu:~/桌面$ sed -n '/Certificate/{p;=}' input
        This is a Certificate Request file:
        Certificate Subject:
    

    awk编程

    awk是三位前辈开发的编程语言,awk是三位创建者的首字母。基本语言与C类似。

    目前,使用的是gawk,Linux系统中/bin目录下有awkgawk两个命令,前者实际上是后者的链接。利用gawk语言可以实现数据查找、抽取文件中的数据、创建管道流命令等功能。

    我们可以简单地将awk编程模型分位三个阶段:

  • 读输入文件执行的执行代码段(由BEGIN关键字标识)
  • 读取输入文件时执行代码段
  • 读输入文件之后的执行代码段(由END关键字标识)
  • 调用方法分为两种:Sehll命令行方式;脚本执行。

    awk模式匹配

    任何awk语句都由模式和动作组成。模式是一组用于测试输入行是否需要执行动作的规则,动作是包含语句、函数和表达式的执行过程。awk支持所有的正则表达式元字符,以及?+两个扩展元字符。

    wsx@wsx-ubuntu:~/桌面$ awk '/^$/{print "This is a blank line."}' input
    This is a blank line.
    This is a blank line.
    This is a blank line.
    This is a blank line.
    This is a blank line.
    

    单引号中间为awk命令,由两部分组成,以“/”符号分隔,^$是模式,花括号部分是动作。该awk表示一旦读入的输入文件是空行,就打印后面的字符串This is a blank line

    使用脚本(将命令输入一个文件中):

    wsx@wsx-ubuntu:~/桌面$ awk -f src.awk input
    This is a blank line.
    This is a blank line.
    This is a blank line.
    This is a blank line.
    This is a blank line.
    

    内容不止这些,我们先谈谈其他概念。

    awk认为输入文件是结构化的,awk将每个输入文件行定义为记录,行中的每一个字符串定义为域,域之间用空格、TAB键或其他符号进行分隔,分隔域的符号就叫分隔符。(这个结构化概念需要理解,很多命令和编程中都有涉及)

    wsx@wsx-ubuntu:~/桌面$ awk '{print $2,$1,$4,$3}' sturecord 
    Hao Li 025------------ njue
    Ju Zhang 025---------- nju
    Bin Wang 025------ seu
    wsx@wsx-ubuntu:~/桌面$ awk '{print $0}' sturecord 
    Li Hao  njue 025------------ 
    Zhang Ju    nju 025---------- 
    Wang Bin    seu 025------
    

    可以通过对域的操作对文本进行重新排列,也可以用print $0输入所有域。

    wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {one=1;two=2}{print $(one+two)}' sturecord 
    

    BEGIN字段中定义onetwo两个变量并赋值。

    -F选项用来改变分隔符,例如只以'\t'为分隔符。

    wsx@wsx-ubuntu:~/桌面$ awk -F'\t' '{print $2}' sturecord 
    025------------ 
    025---------- 
    025------
    

    注意-F-f的区别。

    awk还提供了另一种更方便的方法改变分隔符。

    wsx@wsx-ubuntu:~/桌面$ cat sturecord 
    Li Hao,njue,025------------ 
    Zhang Ju,nju,025---------- 
    Wang Bin,seu,025------
    wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=","}{print $1, $3}' sturecord 
    Li Hao 025------------ 
    Zhang Ju 025---------- 
    Wang Bin 025------
    

    关系和布尔运算符

    awk定义了一组关系运算符用于awk模式匹配。如下表

    用/etc/passwd文件做个例子

    # 第1域匹配root
    wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} $1~/root/' /etc/passwd
    # 全部域匹配root
    root:x:0:0:root:/root:/bin/bash
    wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} $0~/root/' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    # 全部域不匹配nologin
    wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} $0!~/nologin/' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    sync:x:4:65534:sync:/bin:/bin/sync
    systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
    systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
    systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
    systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
    syslog:x:104:108::/home/syslog:/bin/false
    _apt:x:105:65534::/nonexistent:/bin/false
    messagebus:x:106:110::/var/run/dbus:/bin/false
    uuidd:x:107:111::/run/uuidd:/bin/false
    lightdm:x:108:114:Light Display Manager:/var/lib/lightdm:/bin
    

    awk条件语句与C类似,有if语句,if/else语句以及if/else else语句三种。

    下面是支持的布尔运算符

    # 多条件精确匹配
    wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} {if($3==10||$4==10) print $0}' /etc/passwd
    # 多条件模糊匹配
    uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} {if($3~10||$4~10) print $0}' /etc/passwd
    uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
    systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
    systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
    systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
    syslog:x:104:108::/home/syslog:/bin/false
    _apt:x:105:65534::/nonexistent:/bin/false
    messagebus:x:106:110::/var/run/dbus:/bin/false
    uuidd:x:107:111::/run/uuidd:/bin/false
    lightdm:x:108:114:Light Display Manager:/var/lib/lightdm:/bin/false
    whoopsie:x:109:116::/nonexistent:/bin/false
    avahi-autoipd:x:110:119:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false
    wsx:x:1000:1000:wsx,,,:/home/wsx:/bin/bash
    nx:x:123:1001::/var/NX/nx:/etc/NX/nxserver
    

    一个awk表达式可以由数值、字符常量、变量、操作符、函数和正则表达式自由组合而成。

    向awk脚本传递参数

    awk脚本内的变量可以在命令行中进行赋值,实现向awk脚本传递参数,变量赋值放在脚本之后、输入文件之前,格式为:

    awk脚本 parameter=value 输入文件

    条件语句和循环语句

    看起来基本和C一样,框架如下——

    if (条件表达式)
    [else
    
    while(条件表达式)
    while(条件表达式)
    
    for(设置计数器初值; 测试计数器; 计数器变化)
    

    数组是存储一系列值的变量,可通过索引来访问数组的值,索引需要用中括号括起,数组的基本格式为:

    array[index]=value

    形式和C一样,但awk数组无需定义数组类型和大小,可以直接赋值后使用。一般用在for循环中