美文网首页linux&shellLinux小推车
[LN_10] Shell编程-正则 & 文本字符处理命

[LN_10] Shell编程-正则 & 文本字符处理命

作者: Fighting_001 | 来源:发表于2019-02-07 02:17 被阅读76次

    目录结构

    一、正则表达式
        1. 正则表达式与通配符
        2. 正则表达式
        3. 正则表达式案例
    二、字符截取命令
        1. 提取列命令:cut
        2. 格式化输出命令:printf
        3. 提取列/字段命令:awk
            1)awk使用规则
            2)BEGIN、END与awk联用
            3)FS内置变量(内置分隔符)
            4)关系运算符
        4. 文本内容替换命令:sed
            1)查看整行
            2)删除整行
            3)行前插入、行后追加
            4)替换整行
            5)字符串替换
    三、字符处理命令
        1. 排序命令:sort
        2. 统计命令:wc
            1)统计当前目录下的文件个数、目录个数
    

    一、正则表达式

    1. 正则表达式与通配符

    正则表达式
    用于描述排列、匹配模式的一种语法规则。主要用于字符串的匹配、查找、替换、分割操作。匹配时可匹配字符名称 / 类型、字符长度(出现次数)...

    通配符

    符号 作用
    * 匹配任意内容(≥0个字符)
    匹配任意一个内容
    [] 匹配中括号中的任意一个字符

    正则表达式 VS 通配符
    1)正则用来匹配文件内容中的字符串,通配符用来匹配文件的名称
    2)正则是包含匹配,通配符是完全匹配
    3)搜索字符串的命令能识别 grep、awk、sed等,搜索文件名的命令能识别 ls、find、cp等

    2. 正则表达式

    基础正则表达式
    <关联> JavaScript正则表达式-知识点整理

    元字符 作用
    * 量词,其前一个字符匹配≥0次
    匹配0次时表示任意字符都ok
    . 除了换行符以外的任意一个字符
    ^ 匹配行首
    如:^hello匹配以hello开头的行
    $ 匹配行尾
    如:hello$匹配以hello结尾的行
    [] 匹配中括号中的任意一个字符
    [^] 匹配除中括号内字符以外的任意一个字符
    如:[^0-9]匹配非数字
    \ 转义符
    {n} 其前的字符出现n次
    如:[0-9]\{4\}匹配4位数,[1][3-9][0-9]\{9\}匹配手机号
    \{n,\} 其前的字符出现≥n次
    \{n,m\} 其前的字符出现≥n次,且≤m次

    对grep命令搜寻匹配到的字符串加色显示

    vim ~/.bashrc
    alias grep='grep --color=auto'
    source ~/.bashrc
    

    <关联> [LN_04] Linux文件处理-常用命令整理

    3. 正则表达式案例

    # 匹配部分日期格式(非绝对严格):YYYY-MM-DD
    ^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}$
    

    grep "^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}$" reg-exp

    # 匹配部分IP地址(非绝对严格):xxx.xxx.xxx.xxx
    ^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$
    

    grep "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$" reg-exp

    二、字符截取命令

    1. 提取列命令:cut

    cut [选项] 文件名
    选项:
    -f  #提取第几列
    -d 分隔符  #按照指定分隔符对列进行分割(默认以 Tab 制表符作为分隔符)
    

    【案例】
    预先创建文件 student.txt

    回顾 grep 命令:

    # 从/etc/passwd文件中提取包含"/bin/bash"的行
    grep "/bin/bash" /etc/passwd
    # 对以上提取的行进行过滤,只提取不包含"root"的行
    grep "/bin/bash" /etc/passwd | grep -v "root"
    # 对以上第2步获取的结果,以分隔符":"进行提取第1列
    grep "/bin/bash" /etc/passwd | grep -v "root" | cut -f 1 -d ":"
    

    ==> grep提取行,cut提取列

    2. 格式化输出命令:printf

    printf '输出类型输出格式' 输出内容
    printf '输出类型 输出格式' 输出内容
    
    输出类型:
    %ns     输出字符串。n表示输出的字符数
    %ni     输出整数。n表示输出的数字个数
    %m.nf   输出浮点数。m表示输出的总位数(整数位+小数位),n表示输出的小数位数,m-n为整数位数
    
    输出格式:
    \a  输出警告声音(限定本地终端)
    \b  输出退格键(Backspace)
    \f  清除屏幕
    \n  换行
    \r  回车
    \t  水平制表符(Tab键)
    \v  垂直制表符(Tab键)
    

    printf '%s\t%s\t%s\t%s\n' $(cat student.txt)

    echo与printf比较:
    echo会按照输入的格式进行输出显示,printf若不进行格式化控制则不会按照输入的格式输出,echo相当于是在printf的基础上进行了改善的输出方式

    在awk命令输出时支持print和printf命令
    print与printf比较:
    print会在每个输出之后自动加上一个换行符(Linux默认没有print命令),printf是标准的格式输出命令,不会自动加入换行符,需要通过手工方式加入换行符

    3. 提取列/字段命令:awk

    1)awk使用规则
    # 提取列/字段:条件符合则执行对应动作;无条件时都会执行动作
    awk '条件1{动作1}条件2{动作2}...' 文件名
    
    条件(Pattern):
    一般使用关系表达式作为条件
    
    动作(Action):
    格式化输出(如:printf输出)
    流程控制语句(如:for循环)
    

    【案例1】从指定的文档中提取指定的字段

    # 方式1:从指定文件中无条件执行提取第2和第4个字段的动作
    awk '{printf $2 "\t" $4 "\n"}' student.txt
    # 方式2:print可在每个输出之后自动加上一个换行符
    awk '{print $2 "\t" $4}' student.txt
    

    awk处理过程描述:

    ==> 逐行处理数据
    Step1-读取第1行:首先读取文档中的第一行数据
    Step2-判断条件:若满足条件,则执行动作;本例为无条件,即所有都满足执行
    Step3-建立变量:将文件名student.txt赋值给$0,$1、$2、$3、$4分别对应作为第1行的第1、2、3、4个字段
    Step4-执行动作:输出第2个字段、水平制表符、第4个字段、换行符
    Step5-读取第2行,判断条件,执行动作
    Step6-读取第3行,...
    ...
    StepN-直至将文档中的所有行都读取完成,执行完成动作为止

    【案例2】提取挂载在根分区/的文件系统所用的容量占比

    # 从光盘分区数据中提取第1和第3个字段
    df -h | awk '{print $5 "\t" $6}'
    
    # 提取挂载点在根目录的一行数据
     df -h | grep "/$"
    # 提取该行数据中 Use%字段值,对应位置变量:$4(具体根据不同系统而相异)
    df -h | grep "/$" | awk '{print $4}'
    # 对以上提取值处理:以 "%"为分隔符提取第 1列数据
    df -h | grep "/$" | awk '{print $4}' | cut -d "%" -f 1
    

    awk与cut对比:
    1)awk对文档中按每个字段提取,逐行处理数据,不需要受分隔符的限制,使用范围相对更广;cut对文档中按列提取,严格收分隔符限制
    2)文档中的数据,若有规范分隔符,cut和awk均可使用;若无规范的分隔符(如:不同长度的空格符),则建议使用awk按照字段提取

    2)BEGIN、END与awk联用
    # 提取student.txt文档中的第2和第4个字段
    # 提取之前输出指定的字符串,提取之后也输出指定的字符串
    awk 'BEGIN{print "Examination Transcript: "}{print $2 "\t" $4}END{print "Date: 2019-01-01"}' student.txt
    
    3)FS内置变量(内置分隔符)
    # 在处理数据(读取第1行数据)之前就指定分隔符,然后再提取数据
    cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN{FS=":"}{print $1 "\t" $3}'
    

    PS:
    1)/etc/passwd文件中数据是以":"作为分隔符,非默认的制表符分隔符
    2)以上若不加BEGIN作为起始条件来指定":"分隔符,则读取第1行数据时是当作无分隔符,作为一个整体字段进行提取,到第2行开始才会按照":"分隔符作为条件来提取数据,故内置分隔符时需要以BEGIN开头

    4)关系运算符
    # 读取成绩单,判断并输出80分及以上的学生Name($2),但不包含Name本身名称
    cat student.txt | grep -v Name | awk '$4>=80 {printf $2 "\n"}'
    

    4. 文本内容替换命令:sed

    sed:是一种几乎包括在所有Unix平台(包括Linux)的轻量级流编辑器。sed主要用来将数据进行选取、替换、删除、新增的命令

    sed [选项] '[动作]' 文件名
    
    选项:
    -n  把经过sed命令处理的行进行输出,不加"-n"则会在sed处理数据的基础上再叠加输出所有数据
    -e  允许对输入数据应用多条sed命令编辑
    -i  不加"-i"只是临时修改(把修改的效果显示在屏幕上,实际的文件并未变化);
        加"-i"则会修改到实际的文件内容,此时需要防止误操作;不输出到屏幕
    
    动作:
    p   打印整行。输出指定的行,如:'np',表示第n行
    d   删除整行。删除指定的行
    i   行前插入。在当前行的前面插入一行or多行
    a   行后追加。在当前行的后面添加一行or多行
    c   替换整行。用"c"后面的字符串替换原数据行
    s   替换字串。用一个字符串替换另一个字符串;格式:"行范围s/旧字串/新字串/g"
    

    行数据操作

    1)查看整行
    # 查看文件中的第2行
    sed -n '2p' student.txt
    
    2)删除整行
    # 删除第2行数据
    sed '2d' student.txt
    # 删除第2到第4行范围内的数据
    sed '2,4d' student.txt
    
    3)行前插入、行后追加
    # 行前插入
    sed '2i ---第1个成绩---' student.txt
    # 行后追加
    sed '2a ---第2个成绩---' student.txt
    # 多命令联合使用
    sed -e '2i ---第1个成绩---' -e '2a ---第2个成绩---' student.txt
    
    4)替换整行
    # 将第4行替换为字串"AAAAAAAAAAAAAAA"
    sed '4c AAAAAAAAAAAAAAA' student.txt
    
    5)字符串替换
    # 在指定行范围内操作
    sed 行范围s/旧字串/新字串/g
    # 对整个文档操作
    sed s/旧字串/新字串/g
    
    # 将第2行中的79替换成100(全局替换),并写入文件中保存
    sed -i '2s/79/100/g' student.txt
    # 替换Bob为"BBB",同时替换Susan为"SSS"
    sed -e 's/Bob/BBB/g;s/Susan/SSS/g' student.txt
    

    三、字符处理命令

    1. 排序命令:sort

    sort [选项] 文件名
    选项:
    -f  忽略大小写
    -n  以数值型进行排序(默认使用字符串型排序)
    -r  反向排序(从大到小)
    -t  指定分隔符(默认分隔符是制表符)
    -k n[,m]    按照指定的字段范围排序:从第n个字段开始到第m个字段结束
               (不加'[,m]'则默认到整个行尾)
    
    # 排序用户信息文件(字母顺序:从小到大)
    sort /etc/passwd
    # 反向排序用户信息文件(从大到小)
    sort -r /etc/passwd
    
    # 指定分隔符为":",用第3个字段排序(开始和结束范围都是第3个字段)
    # 第3个字段为数字,需要加"-n"指定为整型数值
    sort -n -t ":" -k 3,3 /etc/passwd
    

    2. 统计命令:wc

    wc [选项] 文件名
    选项:
    -l  只统计行数
    -w  只统计单词数
    -m  只统计字符数
    
    1)统计当前目录下的文件个数、目录个数

    应用1:统计当前目录下文件的个数

    # 列出当前目录下所有文件的详细信息,查找以"-"开头的行,并统计行数
    ll | grep "^-" | wc -l
    

    应用2:统计当前目录下目录的个数

    ll | grep "^d" | wc -l
    

    应用3:统计当前目录下文件的个数(包括子目录中的文件)

    ls -lR | grep "^-" | wc -l
    

    应用4:统计当前目录下目录的个数(包括子目录中的目录)

    ls -lR | grep "^d" | wc -l
    

    相关文章

      网友评论

        本文标题:[LN_10] Shell编程-正则 & 文本字符处理命

        本文链接:https://www.haomeiwen.com/subject/blyvsqtx.html