美文网首页
Shell编程之正则表达式(awk)

Shell编程之正则表达式(awk)

作者: 你好树洞先生 | 来源:发表于2019-12-24 11:16 被阅读0次

    正则之Awk

    1.什么是awk:

    awk不仅仅是一个文本处理工具,同时也是一门编程语言,

    是linux上功能最强大的数据处理工具之一。

    2.awk 语法格式:

    awk [options] 'commands' filenames

    awk [options] -f awk-script-file filenames

    处理的文件是/etc/hosts 总共三行

    BEGIN 行处理前动作 {}行处理中 END行处理后

    BEGIN{print 1/2} {print "OK"} END{print "Over"}

        0.5            ok            GameOver

                         ok

                         ok

    #命令 command

    行处理前      行处理          行处理后

    BEGIN{}        {}              END{}

    #BEGIN发生在读文件之前

    [root@Shell ~]# awk 'BEGIN{print 1/2}'

    0.5

    #BEGIN在行处理前,修改字段分隔符

    [root@shell ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd

    #BEGIN在行处理前,修改字段读入和输出分隔符

    [root@shell ~]# awk 'BEGIN{FS=":" OFS="---"}{print $1,$2}' /etc/passwd

    #示例:

    [root@shell ~]# awk 'BEGIN{print 1/2} {print "ok"} END{prrint "Game Over"}' /etc/hosts

    0.5

    ok

    ok

    ok

    Game Over

    =========================================

    3.awk 命令格式:

    #示例1,匹配awk 'pattern' filename

    [root@shell ~]# awk '/root/' /etc/passwd

    #示例2,处理动作 awk '{action}' filename

    [root@shell ~]# awk -F:'{print $1}' /etc/passwd

    =========================================

    示例3,匹配+处理动作 awk 'pattern {action}' filename

    [root@shell ~]# awk -F ':' '/root/{print $1,$3}' /etc/passwd

    [root@shell ~]# awk 'BEGIN{FS=":"} /root/{print $1,$3}' /etc/passwd

    示例4:判断大于多少则输出什么内容 command |awk 'pattern {action}'

    [root@shell ~]# df |awk '/\/$/ {if($3>50000)print $4}'

    4.Awk工作原理:

    # awk -F:'{print $1,$3}' /etc/passwd

    1.awk将文件中的每一行作为输入,并将每一行赋值给内部变量$0,以换行符结束。

    2.awk开始进行字段分隔,每个字段存储在已编号的变量中,从$1开始[默认空格分隔]

    3.awk默认字段分隔符是由内部FS变量来确定,可以使用-F修订。

    4.awk行处理时使用了print函数打印分割后的字段。

    5.awk在打印后的字段加上空格,因为$1,$3之间有一个逗号,逗号被映射至OFS内部变量中,

    称为输出字段分隔符。OFS默认为空。

    6.awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,

    然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕。

    =========================================

    例子1:

    [root@shell ~]# cat awk_file.txt

    ll 1989 55 56 63

    kk 1990 60 57 64

    hh 1991 70 58 65

    jj 1992 80 59 66

    mm 1993 90 60 67

    1)awk指定多个分隔符,awk默认以空白行作为分隔符

    #1.如何查看文件中的第一列:

    [root@shell ~]# awk '{print $1}' awk_file.txt

    ll

    kk

    hh

    jj

    mm

    #2.如果有的文件不是以空格为分隔符怎么办?

    比如:/etc/passwd

    [root@shell ~]# awk -F ":" '{print $2}' awk_file.txt

    1989 55 56 63

    1990 60 57 64

    [root@shell ~]# awk -F "[: ]" '{print $2}' awk_file.txt

    1989

    1991

    1992

    1993

    1994

    =========================================

    #[: ]+

      1.连续的多个冒号当一个分隔符

      2.连续的多个空格当一个分隔符

      3.连续空格和冒号也当做一个分隔符

    "#[: \t]+"

      4.连续空格和tab也当做一个分隔符

      5.连续tab也当做一个分隔符

      6.连续的冒号空格tab都算一个分隔符

    ===================================

    例子2:

    统计一行里有多少个数量,一共5个

    [root@shell ~]# awk '{print NF}' awk_file.txt

    5

    5

    5

    5

    5

    ======================================

    1.awk内置变量NF,保存每行的最后一列

    #1.通过print打印,NF和$NF,你发现了什么?

    [root@shell ~]# awk '{print NF,$NF}' awk_file.txt

    5 63

    5 64

    5 65

    5 66

    5 67

    #2.使用$NF为什么就能成功?(因为NF变量保存的是每一行的最后一列)

    [root@shell ~]# awk '{print $NF}' awk_file.txt

    63

    64

    65

    66

    67

    #3.如果一个文件很长,靠数列数需要很长的时间,

    那么如何快速打印倒数第二列?

    [root@shell ~]# awk '{print $(NF-1)}' awk_file.txt

    56

    57

    58

    59

    60

    2)awk内置变量NR,表示记录行号

    #1.使用pring打印NR,会发现NR会记录每行文件的行号

    [root@shell ~]# awk '{print NR,$0}' awk_file.txt

    1 ll 1989 55 63

    2 kk 1990 60 64

    --------------------------------------------

    #2.[root@shell ~]# awk 'NR==3{print $0}' awk_file.txt

    hh 1991 70 58 65

    #3.那如果我们想打印第二行到第三行的内容怎么办?

    [root@shell ~]# awk 'NR>1&&NR<4 {print NR,$0}' awk_file.txt

    2 kk 1990 60 57 64

    3 hh 1992 70 58 65

    #4.那如果只想打印第三行,该怎么办?

    [root@shell ~]# awk 'NR==3 {print NR,$00}' awk_file.txt

    3 hh 1992 70 53 63

    #5.那如果既想打印第三行,又想打印第一列?

    [root@shell ~]# awk 'NR==3 {print NR,$1}' awk_file.txt

    3 hh

    ===============================================

    4.awk内置变量,$0保存当前记录的内容

    [root@shell ~]#  awk '{print $0}' /etc/passwd 

    5.awk内置变量,FS指定字段分隔符,默认是空格?

    #以冒号作为字段分隔符:

    [root@shell ~]#  awk -F:'/root/{print $1,$3}' /etc/passwd

    [root@shell ~]#  awk '{BEGIN{FS=":"}  {print $1,$3} '  /etc/passwd

    内置变量

    NF      #记录每行内容的最后一列,通常记录的是一个整数

    NR     #记录行号

    FS     #指定字段分隔符

    OFS  #指定输出字段分隔符

    $0     #代表每行的所有内容

    $1,$2  #指定字段分隔符后,每列的内容

    print   #输出内容

    printf  #格式化输出

    ===============================================

    5.awk模式匹配与动作处理

    awk语句都由模式和动作组成,模式部分动作语句何时触发事件,如果省略模式部分,动作将时刻保持执行状态,模式可以是条件语句或复合语句或正则表达式。

    (1)正则表达式

    #匹配记录(整行)

    [root@shell ~]# awk '/^root/' /etc/passwd 

    #匹配字段,匹配操作符(~ !~)

    [root@shell ~]#  awk '$1~/^root/' /etc/passwd

    (2)条件表达式

    [root@shell ~]# awk -F: '{if($3>300) print $0}' /etc/passwd

    (3)条件判断:

    //统计系统用户数量

    [root@shell ~]#  awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd

    [root@shell ~]#  awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd

    相关文章

      网友评论

          本文标题:Shell编程之正则表达式(awk)

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