zoukankan      html  css  js  c++  java
  • awk(gawk)

      awk,逐行处理文本内容。Linux里的awk其实是“gawk”。

      使用格式:

        awk [选项] '模式匹配 {命令 命令参数}' file1, file2, ……

    支持的选项说明

    -f program-file

    --file program-file

    从文件接收 awk指令,可以同时指定多个文件

    -F fs

    --field-separator fs

    指定(fs)列分隔符

    -v var=value

    --assign var=value

    为 BEGIN 块定义变量var,指定其值为value

    -d[file]

    --dump-variables[=file]

     

     

      demo,ipaddress俩文件的内容是环网柜、柱上开关柜的主、备ip地址。分别以制表符、冒号分割。

    $ cat demo
    RingNetwork     181.36.1.8      182.36.4.8
    Switch          181.32.1.22     182.36.4.42
    Switch          181.32.1.23     182.36.4.43
    $ cat ipaddress
    R:181.36.1.8:182.36.4.8
    S:181.32.1.22:182.36.4.42
    S:181.32.1.23:182.36.4.43

      命令:

        print  打印输出,参数之间使用逗号分隔。

        printf  输出时,需要指定输出格式。

    printf 输出格式铆定符
    格式
    铆定符
    效果说明例子(页面最下边)
    %c 打印成 ascii 码表的“char”形式
    2.1
    %s 输出字符串
    2.2
    %d, %i 十进制数的整数部分
    2.3
    %o 无符号八进制数的整数部分
    2.4
    %x, %X 同上,大小的区别表示[a-f],[A-F]
    2.5
    %u 无符号的十进制数的整数部分  
    %f 浮点数
    2.6
    %% 输出%,相当于\输出反斜线一样
     
    %10s 预留10个字符位置,右对齐
     
    %-10s
    左对齐显示  

      常见变量:

        FS  输入列分割符

        OFS  输出列分隔符

        RS  输入行分割符

        ORS  输出行分割符

        NF  记录数(当前处理的)

        NR  行数(当前处理)

        FNR  行数(当前文件)

     


     

    1 输出文本 print

    1.1 输出指定列信息

      取出每个设备的主ip地址信息

    $ awk '{print $2}' demo
    181.36.1.8
    181.32.1.22
    181.32.1.23

    1.2 列分隔符

    1.2.1 列的引用表示

      $1、$2……分别表示当前处理行的第一列、第2列……。$0表示当前行所有列。

    $ awk '{print $0}' demo
    RingNetwork     181.36.1.8      182.36.4.8
    Switch          181.32.1.22     182.36.4.42
    Switch          181.32.1.23     182.36.4.43
    $ awk '{print $1,$2,$3}' demo
    RingNetwork 181.36.1.8 182.36.4.8
    Switch 181.32.1.22 182.36.4.42
    Switch 181.32.1.23 182.36.4.43

      输出awk处理的文件的列数。

    $ awk '{print NF}' demo
    3
    3
    3
    $ awk '{print NF}' ipaddress
    1
    1
    1
    $ awk '{print NF}' demo ipaddress
    3
    3
    3
    1
    1
    1

    1.2.2 输出列分割符

      awk默认输出分隔符是空格,可以通过变量“OFS”修改,需要使用双引号。

    $ awk 'BEGIN{OFS=":"} {print $1,$2,$3}' demo
    RingNetwork:181.36.1.8:182.36.4.8
    Switch:181.32.1.22:182.36.4.42
    Switch:181.32.1.23:182.36.4.43

    1.2.3 输入列分割符

      awk以空白符作为默认输入分割符,就算分割不是制表符,而是某些个空格符也一样能准确取到主ip。同时,还可以修改默认输入分割符,通过变量“FS”显式指定分割符为空格。

     awk 'BEGIN{FS=":"} {print $1,$2,$3}' ipaddress
    R 181.36.1.8 182.36.4.8
    S 181.32.1.22 182.36.4.42
    S 181.32.1.23 182.36.4.43

       或者在选项“F”里指定分隔符。

    $ awk -F: '{print $2}' ipaddress
    181.36.1.8
    181.32.1.22
    181.32.1.23

    1.3 行分隔符

      输出当前处理的行数

    $ awk '{print NR}' demo ipaddress
    1
    2
    3
    4
    5
    6
    $ awk '{print FNR}' demo ipaddress
    1
    2
    3
    1
    2
    3

    2 输出文本 printf

    2.1 验证printf命令的%c格式,是把ASCII的Dec列内容转换成Char列内容。(是不是有点像发电报一样)

    [root@hp430G2 demo]# cat num
    72
    101
    108
    108
    111
    [root@hp430G2 demo]# awk '{printf("%c", $1)}END{printf("
    ")}' num
    Hello
    
    [root@hp430G2 demo]# cat num
    72 101 108 108 111
    [root@hp430G2 demo]# awk '{printf("%c%c%c%c%c", $1,$2,$3,$4,$5)}END{printf("
    ")}' num
    Hello

      因为,printf默认不换行,所有要借助END,而且顺便借助不换行完成单词的拼接。而且,模式数量必须与变量数量(列)对应起来。

     

    2.2 验证printf命令的%s格式

    [root@hp430G2 demo]# cat alpha
    Hello
    [root@hp430G2 demo]# awk '{printf("%s", $1,$2,$3,$4,$5)}END{printf("
    ")}' alpha
    Hello

     

    2.3 验证printf命令的%d、%i格式

    [root@hp430G2 mag37]# cat int
    3.1415926
    [root@hp430G2 mag37]# awk '{printf("%i", $1)}END{printf("
    ")}' int
    3
    [root@hp430G2 mag37]# awk '{printf("%d", $1)}END{printf("
    ")}' int
    3

    2.4 验证printf命令的%o指定输出八进制格式。

    [root@hp430G2 mag37]# cat oct
    181.37.1.42
    182.37.4.42
    [root@hp430G2 mag37]# awk -F. '{printf("%o.%o.%o.%o
    ", $1,$2,$3,$4)}' oct
    265.45.1.52
    266.45.4.52

    2.5 验证printf命令的%X、%x指定输出十六进制格式,分别输出字母部分的大小写。

    [root@hp430G2 mag37]# cat hex
    181.37.1.42
    182.37.4.42
    [root@hp430G2 mag37]# awk -F. '{printf("%x.%x.%x.%x
    ", $1,$2,$3,$4)}' oct
    b5.25.1.2a
    b6.25.4.2a
    [root@hp430G2 mag37]# awk -F. '{printf("%X.%X.%X.%X
    ", $1,$2,$3,$4)}' oct
    B5.25.1.2A
    B6.25.4.2A

    2.6 验证%f,没搞明白,这里输出分割符不能成功指定。

    [root@hp430G2 mag37]# cat float
    181.37 1.42
    182.37 4.42
    [root@hp430G2 mag37]# awk '{printf("%F %F
    ",$1,$2)}' float
    181.370000 1.420000
    182.370000 4.420000

      可不可以这样看,在使用了printf时,输出控制的权利就完全交割了,变量被失效了。

    3 数学运算

    3.1 算术运算

    BEGIN{
    r=5
    R=r*2
    print R
    y=R*3.14
    print y
    }

      支持常见操作符:+ - * / ^ % =,分别表示加、减、乘、除、次方、取余数、赋值。


    3.2 条件运算

      支持条件判断:x < y、x <= y、x > y、x >= y、x == y、x != y、x ~ RE、x !~ RE、&&、||,比较字符串的大小关系、相同关系、匹配正则表达式、多个表达式之间的关系。以及条件表达式:?:

    3.3 匹配运算

    #!/bin/awk -f
    
    $1 ~ /^s/ {print}

      * 注意与上边例子中“print”命令使用“花括号”的位置。

    4 模式匹配

    4.1 逻辑匹配

    输出模式匹配的行;首列大于19、在7到11之间、等于12。

    awk '$1>19 {print}' demo.txt
    awk '$1==12 {print}' demo.txt

     

    下边的命令,会使得输出值发生变化;为输出结果重新赋值。

    awk '$1=12 {print}' demo.txt

    4.2 使用正则表达式匹配

    使用正则表达式匹配;大写字母后面跟着小写字母、文件大小为2开头、取大小值

    awk '/[[:upper:]][[:lower:]]/ {print}' demo.txt
    awk '/:..[[:space:]]*2/ {print}' demo.txt
    awk '/grep/ {print}' demo.txt

    4.3 混合模式匹配

    找出以两个数字开头、第4列大于40、并且包含一个大写字母后边跟着一个小写字母的行。

    awk '/^[[:digit:]]/ && $4>40 && /[[:lower:]]/ {print}' demo.txt
    awk '$1>7 && $1<11 {print}' demo.txt

    4.4 区间模式

    awk '/^8/,$4==37 {print}' new.txt

    4.5 读取数据文件之前的“BEGIN模式”“END”

      由于“begin”块内的命令是在读取文件之前就开始执行的,所以这里的命令不能是操作文件数据的命令。通常可以用来初始化变量。执行顺序就是从“BEGIN”开始,到“模式匹配阶段的数据处理命令”,最后执行“END”。

    awk 'BEGIN{print "This is all lines in new.txt."} {print}' new.txt

    END模块(这里的“BEGIN”、“END”必须是大写的)

    awk '{print} END{print "File is over."}' new.txt

      在该模式下,awk变量的定义、赋值、引用。

    [awk@h p]$ cat demo2.txt
    This is for test of awk's begin and end.
    [awk@h p]$ cat print.awk
    #!/bin/awk -f
    
    BEGIN{
    print "begin"
    }
    
    {print}
    
    END{
    print "end
    over"
    }
    [awk@h p]$ ./print.awk demo2.txt
    begin
    This is for test of awk's begin and end.
    end
    over

    3 变量

    变量
    释义
    $0
    当前正在处理的记录
    $n
    第n个字段的值
    NF
    当前处理记录的字段数
    NR
    当前已经读入的记录数
    FILENAME
    正在处理的数据文件的名称
    FS
    字段分割符(默认空格、或制表符)
    RS
    记录分割符(默认换行)

      NF表示字段数,更有用的可以得到最后一个字段(当每行不同字段时更有用)。可以获取文件名、文件大小

    [root@Rsync logs4developers]# tree -fh | grep "M" | awk '{print $NF ,$(NF-1)}'
    
    

    3.1 普通变量

    [awk@h p]$ cat demo1.awk
    #!/bin/awk -f
    
    BEGIN{
    age=33
    say_hello="hello"
    print age
    print say_hello
    [awk@h p]$ awk -f demo1.awk
    33
    hello

    3.2 内置变量

    [awk@h p]$ cat ip_port.txt
    172.17.36.40:22,3306
    10.134.1.4:22,1521
    [awk@h p]$ awk 'BEGIN{FS=":"; RS="
    "; RS=""; ip="ip = "; port="   port = "} {print ip $1 port $2}' ip_port.txt
    ip = 172.17.36.40   port = 22,3306
    ip = 10.134.1.4   port = 22,1521

    4 使用脚本

    4.1 在脚本中执行 awk 命令

    [web@h p]$ cat my_awk.sh
    #!/bin/awk -f
    
    {print}
    [web@h p]$ ./my_awk.sh demo.txt

    4.2 交互模式下的“文件结束符”

    运行这个脚本

    #!/bin/awk -f
    
    BEGIN{
    exitpro="press <ctrl+d> exit the script."
    print "test is beginning."
    print exitpro
    print "============================="
    }
    
    {print}
    
    END{
    print "============================="
    print "test is over."
    }

      脚本运行后,终端等待输入内容,输入结束时需要给脚本文件发送“EOF”信号。按组合键“ctrl+d”退出(Windows平台“ctrl+z”)。

    4.3 体会命令执行模式

    运行这个脚本

    #!/bin/awk -f
    
    {
    print
    print "Have two print."
    }

      当命令“print”没有“file“时,以交互模式执行;执行时这里也是需要“EOF”的,第一条命令执行结束后,执行下一条命令;但是“打印”命令始终是需要一个“EOF”的,而这个信号的接收不会影响后边命令的执行。

      看到上边的例子,我会以为“需要在EOF是因为有个命令的缘故”。去掉脚本中的“print”命令,结果发现依然需要。不同之处在于没有回显。

      在脚本执行时,添加一个“demo.txt”。发现脚本依然可以执行,说明 awk 在执行时,“pattern”、“actions”都可以不需要。

    4.4 命令的执行顺序

      awk处理“file”时,按照“记录”依次处理。其中的命令执行是每条命令执行完读入的一条“记录”下一条命令接着处理同样一条“记录”。

    [awk@h p]$ cat demo.txt
    This is row1.
    This is row2.
    This is row3.
    [awk@h p]$ cat print-file.awk
    #!/bin/awk -f
    
    {
    print
    print
    }
    [awk@h p]$ 
    This is row1.
    This is row1.
    This is row2.
    This is row2.
    This is row3.
    This is row3.

    6 函数

    6.1 字符串函数

    函数释义
    index(s1,s2) 返回 s2 在 s1 中的位置;返回值从“1”开始,“0”代表不存在
    length(s1) 返回字符串的长度;返回整数值
    match(s1,RE) 查找匹配正则表达式匹配的字符串;涉及变量“RSTART”,“RLENGTH”
    split(s1,array,sep) 以“sep”分割“s1”后,返回“array”
    [awk@h p]$ awk 'add=index($0,"sunny") {print add}' demo.txt
    1
    [awk@h p]$ awk '{print index($0,"sunny")}' demo.txt
    1
    0

     6.2 算术函数

    函数释义
    int(x) 返回整数部分
    rand() 反馈0~1之间的随机数
    srand([x]) 反回一个基于“x”的随机数

     

    7 数组

    7.1 数组的定义与引用

    #!/bin/awk -f
    
    BEGIN{
    port[1]=22
    port[2]=3389
    port[3]=10022
    
    print port[1],port[2],port[3]
    }

     

    7.2 数组遍历

    借用“for 循环”遍历数组元素

    8 流程控制

    9 格式化输出

    10 shell交互

    一切代码都是为了生活,一切生活都是调剂
  • 相关阅读:
    文件上传
    使用servlet+jdbc+MD5实现用户加密登录
    JDBC入门
    springmvc(三)
    springmvc(二)
    springmvc(一)
    JavaScript总结(一)
    Spring的AOP面向切面编程
    Spring框架(三)
    Spring框架(二)
  • 原文地址:https://www.cnblogs.com/argor/p/7910207.html
Copyright © 2011-2022 走看看