美文网首页
shell之awk

shell之awk

作者: IT小池 | 来源:发表于2019-07-28 14:38 被阅读0次

    awk是一个文本处理工具,通常用于处理数据并生成结构报告。

    语法格式:
    第一种形式:awk 'BGGIN{}pattern{commands}END{}' file_name
    第二种形式:standard output | awk 'BGGIN{}pattern{commands}END{}' file_name
    说明:
    BEGIN{} 正式处理数据之前执行
    pattern{} 匹配模式
    {commands} 处理命令,可能多行
    END{} 处理完所有匹配数据后执行

    awk选项

    选项 说明
    -v 参数传递
    -f 指定脚本文件
    -F 指定分隔符
    -V 查看awk版本号

    如:

    # -v
    [root@VM_0_14_centos test]# num=10
    [root@VM_0_14_centos test]# var=20
    [root@VM_0_14_centos test]# awk -v num1="$num" -v num2="$var" 'BEGIN{print num1,num2}'
    # -f
    [root@VM_0_14_centos test]# num=10
    [root@VM_0_14_centos test]# var=20
    [root@VM_0_14_centos test]# awk -v num1="$num" -v num2="$var" -f test.awk
    # -F
    [root@VM_0_14_centos test]# awk -F ":" '{print $1}' /etc/passwd
    

    注:在引用变量的时候,最好加双引号""

    内置变量

    $0 整行内容

    [root@VM_0_14_centos test]# awk '{print $0}' test.txt
    

    $1-$n 当前行的第 1 - n 个字段(默认 冒号: / tab键 切割)

    [root@VM_0_14_centos test]# awk '{print $2}' test.txt
    

    NF 当前行的字段个数,也就是有多少列

    [root@VM_0_14_centos test]# awk '{print NF}' test.txt
    

    输出每行中最大的字段(一列)$NF

    [root@VM_0_14_centos test]# awk '{print $NF}' test.txt
    

    NR 当前行的行号,从 1 开始计数

    [root@VM_0_14_centos test]# awk '{print NR}' test.txt
    

    FNR 多文件处理时,每个文件行号单独计数,都是从 0 开始

    [root@VM_0_14_centos test]# awk '{print FNR}' test.txt
    

    FS 输入字段分隔符,不指定默认以空格或 tab 键分割

    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"}{print $0}' test.txt
    

    RS 输入行分隔符,默认回车换行

    [root@VM_0_14_centos test]# awk 'BEGIN{RS="--"}{print $0}' test.txt
    

    OFS 输出字段(列)分隔符,默认为空格

    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":";OFS='&'}{print $1,$2}' test.txt
    

    ORS 输出行分隔符,默认为回车换行

    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":";OFS="&";ORS="@"}{print $1,$2}' test.txt
    

    FILENAME 当前输入的文件名字

    [root@VM_0_14_centos test]# awk '{print FILENAME}' test.txt
    

    ARGC 命令行参数个数

    [root@VM_0_14_centos test]# awk '{print ARGC}' test.txt
    

    ARVG 命令行参数数组

    printf

    printfprint都是输出,只不过,print有默认的分隔符(空格 / tab键),而printf没有默认的分割符,且还能美化输出(如:左对齐 / 右对齐)

    printf格式说明符:
    %s 打印字符串

    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%-20s %-20s\n",$1,$7}' test.txt
    

    说明:%20s:是占20个字符,在20字符后再输出第二个字段值 $7;且两个 %s 之间有空格,表示输出的两个字段 $1 $7直接以空格间隔。\n是一次完整的输出后,回车换行显示第二次完整输出。减号(-) 是左对齐显示输出
    %d 打印十进制数
    %f 打印一个浮点数
    %x 打印打印十六进制数
    %o 打印八进制数
    %e 打印数字的科学计数法形式
    %o 打印单个字符的 ASCLL码

    printf格式修饰符:
    - 左对齐
    + 右对齐
    # 显示8进制或16进制在前面加 #
    示例:

    1. 以字符串格式打印 test.txt 中的第7个字段,以 : 作为分隔符
    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%s\n",$7}' test.txt
    
    1. 以10进制格式打印 test.txt 中的第3个字段,以 : 作为分隔符
    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%d\n",$3}' test.txt
    
    1. 以浮点数格式打印 test.txt 中的第3个字段,以 : 作为分隔符
    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%0.2f\n",$3}' test.txt
    

    说明:0.2 是保留2位小数

    1. 以16进制格式打印 test.txt 中的第3个字段,以 : 作为分隔符
    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%#x\n",$3}' test.txt
    

    说明:# 显示8进制或16进制在前面加 #

    1. 以8进制格式打印 test.txt 中的第3个字段,以 : 作为分隔符
    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%#o\n",$3}' test.txt
    
    1. 以科学计数法格式打印 test.txt 中的第3个字段,以 : 作为分隔符
    [root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%e\n",$3}' test.txt
    

    awk匹配模式

    1. RegExp

    如:1. 匹配 /etcpasswd 文件行中含有 root 字符串的所有行

    [root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
    

    如:2. 匹配 /etcpasswd 文件行中以 root 开头的所有行

    [root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}/^root/{print $0}' /etc/passwd
    
    2. 运算符匹配
    1. 关系运算符
    运算符 说明
    < (小于)
    > (大于)
    <= (小于等于)
    >= (大于等于)
    == (等于)
    != (不等于)
    ~ (匹配正则表达式)
    != (不匹配正则表达式)

    如:1. 匹配 /etc/passwd 文件中第 3 个字段(数值)小于50的所有行信息

    [root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
    

    如:2. 匹配 /etc/passwd 文件中第 7 个字段为 /bin/bash 的所有行信息

    [root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
    
    1. 布尔运算符匹配
    运算符 说明
    ||
    &&
    !

    如:1. 匹配 /etc/passwd 文件中包含 sync 或 root 的所有行信息

    [root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$1=="root" || $1=="sync"{print $0}' /etc/passwd
    

    如:2. 匹配 /etc/passwd 文件中第3个字段小于50 且第 4 个字段大于50的所有行信息

    [root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$3<50 && $4>50{print $0}' /etc/passwd
    
    1. 动作表达式中的 算术运算符
    运算符 说明
    +
    -
    *
    /
    %
    ^ 或 ** 乘方
    ++x 在返回 x 变量之前,x 变量加1
    x++ 在返回 x 变量之后,x 变量加1

    如:

    # 加 +
    // num2未定义就是 0
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2+=num1;print num1,num2}'
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1+num2}'
    # 减 -
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1-num2}'
    # 乘 *
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1*num2}'
    # 除 /
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1/num2}'
    // %0.2f 保留两位小数
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;printf "%0.2f\n",num1/num2}'
    # 模 %
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1%num2}'
    # 乘方 ^ 或 ** 
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print "%0.2f\n",num1**num2}'
    # ++x
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=++num1;print num1,num2}'
    # x++
    [root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=num1++;print num1,num2}'
    

    如:统计 test.txt 文件中的空白行数量

    [root@VM_0_14_centos /]# awk '/^$/{total++}END{print total}' /test.txt
    
    3. awk动作中的条件及循环:

    如:判断 test.txt 文件中第三列数字大于50且小于100的行

    [root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}{if($3>50 && $3<100) print $0}' /test.txt
    

    awk中的字符串函数:

    函数名 解释 函数返回值
    length(str) 计算字符串长度 整数长度值
    index(str1,str2) 在str1中查找str2的位置 返回值为位置索引,从1计数
    tolower(str) 转换为小写 转换后的小写字符串
    toupper(str) 转换为大写 转换后的大写字符串
    substr(str,m,n) 从str的m个字符开始,截取n位 截取后的子串
    split(str,arr,fs) 按fs切割字符串,结果保存arr 切割后的子串的个数
    match(str,RE) 在str中按照RE查找,返回位置 返回索引位置
    sub(RE,RepStr,str) 在str中搜索符合RE的字串,将其替换为RepStr,只替换第一个 替换的个数
    gsub(RE,RepStr,str) 在str中搜索符合RE的字串,将其替换为RepStr,替换所有 替换的个数

    注:awk中的下标是从 1 开始,shell中下标是从 0 开始
    如:1.以 : 为分隔符,返回 /etc/passwd 中的每行中每个字段的长度:
    新建文件 test.awk(后缀是.awk),新手不熟悉先这样新建文件写,内容如下

    BEGIN  {
        FS=":"
    }
    {
        i=1
        while(i <= NF){ # NF 当前行的字段个数,也就是有多少列
            if(i == NF)
                  printf "%d",length($i)
             else
                  printf "%d:",length($i)
        }
         print "" # print 输出默认就是空格换行
    }
    

    执行的时候,输入命令 awk -f test.awk /etc/passwd-f是指引入文件

    相关文章

      网友评论

          本文标题:shell之awk

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