Shell脚本之awk文本编辑器语法(一)

AWK  ――是一种用于处理文本的编程语言工具。
    英文原义:Aho、Weinberger、Kernighan
    中文释义:三位创造者Aho、Weinberger和Kernighan统称

     AWK 在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。

    awk 之所以成为一种优秀的程序设计语言的原因之一是内置函数的使用,awk定义并支持了一系列的内置函数,由于这些函数的使用,使得awk提供的功能更为完善和强大。

常用语法:
    awk    [options]    'commands'        testfiles
    
options选项
    -F    定义字段分隔符,默认分隔符为连续空格或制表符
        用$1,$2,$3等顺序表示files中每行以间隔符号分隔的各列不同域
    -v    定义变更并赋值,也可以借用次方式从shell变量中引入变量
使用示例:
[root@localhost test]# awk -F":" '{print $1,$7}' testfile
        以冒号作为分隔符,打印第1和第7个字段
[root@localhost test]# awk -F"[:/]" '{print $1,$7}' testfile
        以冒号或斜杠 / 作为分隔符,打印第1第7个字段
[root@localhost test]# awk -F":/" '{print $1,$7}' testfile
        以冒号加斜杠 “:/”整体作为分隔符
       
-----------------------------------------------------------   
command
    读前处理    行处理        读后处理
        1、读前处理    BEGIN{awk_cmd1;awk_cmd2;}
        2、行处理:定址    命令
        定址方法:正则,变量,比较,关系运算
                正则需要用 / / 包裹起来
        常用正则:
            ^    行首                $    行尾
              .    除了换行符以外的任意单个字符
              *    前导字符的零个或多个
              .*    所有字符
              []    字符组内的任一字符
              [^]    对字符组内的每个字符取反(不匹配字符组内的每个字符)
              ^[^]    非字符组内的字符开头的行
              [a-z] 小写字母
              [A-Z] 大写字母
              [a-Z] 小写和大写字母
              [0-9] 数字
              \<    单词头,以空格或特殊字符做分隔,连续的字符串被当做单词
              \>    单词尾

        扩展正则
              ?         前导字符零个或一个
              +         前导字符一个或多个
              abc|def         abc或def
              a(bc|de)f         abcf 或 adef
              x\{m\}           x出现m次
              x\{m,\}          x出现m次至多次(至少m次)
              x\{m,n\}         x出现m次至n次

        NR变量定址,NR 表示AWK读入的行数
        FNR表示读入行所在文件中的行数
         
        逻辑运算――可直接引用域进行运算
            ==    >=    <=    !=    >    <    ~    !~
            如:# awk 'NR==1 {print}'  /etc/passwd
                    root:x:0:0:root:/root:/bin/bash
                           
        命令    如:{print $1,$2}
       
    3、读后处理
        END {awk_cmd1;awk_cmd2;}

---------------------------------------------------------------
AWk的变量
    NR     AWK处理的总行数
    FNR   AWK处理的当前文件的行数,非全部
    FS     字段分隔符,默认为连续空格或制表符,可以使用多个不同的符号做分隔符,也可在options出使用  -F[:/]    指定分隔符
    OFS   输出字符的分隔符 默认是空格
             如:# awk -F: 'OFS="***" {print $1,$2}' /etc/passwd
                      root***x
    NF     当前读入行的字段个数
    ORS   输出行的分隔符,默认是换行
        # awk -F: 'ORS="***" {print $1,$2}' /etc/passwd
        root x***bin x***
    FILENAME     当前文件名

---------------------------------------------------------------
引用shell变量的方法:
(1)使用 -v 引用变量值
[root@localhost test]# a=5
[root@localhost test]# awk -v c=$a  -F:  'NR < c {print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
 
(2)把整个命令拆开传递,让shell变量外露
[root@localhost test]# a=5
[root@localhost test]# awk -F: 'NR < '$a'{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin

------------------------------------------------------------
操作符
    赋值        =         +=         -=         /=         *=
    &&    ――逻辑与    ||――逻辑或     !――逻辑非
         
    匹配正则或不匹配,正则需要用 /正则/ 包围住
        ~          !~
    关系 比较字符串,要把字符串用双引号引起来
        <         <=     >     >=     !=         ==
    字段引用
        $     字段引用需要加$        而变量引用直接用变量名取
    运算符
        +     -     *     /     %         ++     --
    转义序列
        \\         \自身
        \$         转义$
        \t         制表符
        \b         退格符
        \r         回车符
        \n         换行符
        \c         取消换行

用法示例:
# awk -F: '$3 >= 30 && $3 <= 40 {print $0}' /etc/passwd
        打印出uid在30到40之间的用户信息行
# awk -F: ' NR >= 30 && NR <= 40 {print NR,$0}' /etc/passwd
        打印出行号在30到40之间的行
# awk -F: ' NR % 2 == 1 {print NR,$1,NF}' /etc/passwd
        打印奇数行
# awk -F: ' NR % 2 == 0 {print NR,$1,NF}' /etc/passwd
        打印偶数行
# awk -F: ' $3 != $4 {print NR,$1,$3,$4}' /etc/passwd
        打印uid和gid不相等的用户信息行
# awk -F: '$7 ~ /bash/ {print NR,$1,$7}' /etc/passwd
        打印第7个字段能匹配 /bash/ 字符串的行
# awk -F: '$7 !~ /nologin/ {print NR,$1,$7}' /etc/passwd
        打印第7个字段不能匹配 /nologin/ 字符串的行
 
------------------------
数组

自定义数组
# awk 'BEGIN{ary[1]="hunan";ary[2]="hubei";print ary[1],ary[2]}'
hunan hubei

# awk 'BEGIN{ary[1]="hunan";ary[2]="hubei";for(i in ary) print ary[i]}'
hunan
hubei

环产生数组和取出数组
# awk 'BEGIN{n=5;for (i=1;i<=n;i++) ary[i]=i+100;for(m in ary) print m,ary[m]}'
    4 104
    5 105
    1 101
    2 102
    3 103

# awk -F: '{ary[NR]=$1}END{for(i in ary){print i,ary[i]}}' testfile
4 dbus
5 usbmuxd
6 hsqldb
7 avahi-autoipd
8 rpc
1 root
2 bin
3 myuser

# awk -F: '{ary[$3]=$1} END {for(i in ary) print i,ary[i]}' testfile


你可能感兴趣的:(linux,shell,awk)