zoukankan      html  css  js  c++  java
  • awk命令用法

      awk:把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理,是一个强大的文本分析工具,在对数据分析并生成报告时很有优势。

      awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

    • 命令格式:
        awk [options] 'program' FILE ...
    其中:
        options:
            -F:指明输入时用到的字段分隔符,默认空白字符;
            -v:指定变量
            -v var=value:自定义变量
        program:
            PATTERN{ ACTION STATEMENTS;...} (语句之间用 ; 分隔)
            PATTERN--模式,这意味着并不是对文件中的每一行进行处理,而是处理那些能够被模式匹配到的行,不跟模式表示全文;
            ACTION--常见的处理机制是打印,命令有print和printf.
    • 变量
      • 常见内置变量  
      FS:切割时的分隔符,默认为空白字符;
      OFS:切割后输出时的分隔符,默认为空白字符;
      RS:输入时的换行符,默认为'
    ';
      ORS:输出时的换行符,默认为'
    ';
      NF:字段数量 ( $NF表示最后一个字段);
      NR:行数;
      FNR:分别计算各文件的行数;
      FILENAME:当前文件名;
      ARGC:命令行参数的个数;
      ARGV:数组,保存的是命令行所给定的各参数
    示例:
       awk -v FS=: '{print $1}' /etc/passwd (相当于awk -F: "{print $1}" /etc/passwd)
       awk -v FS=: -v OFS=, '{print $1,$2}' /etc/passwd
       awk -v RS=' ' '{print}' /etc/issue
       awk '{print NF}' /etc/fstab (可对比 awk '{print $NF}' /etc/fstab,$NF表示最后一个字段)
       awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue (命令行参数有3个,分别为awk,/etc/fstab,/etc/issue)
       awk 'BEGIN{print ARGV[#]}' /etc/fstab /etc/issue (#表示索引下标)
      • 自定义变量
    种方式可自定义变量:
        (1) -v var=value
        (2) 在program中直接定义
    示例:
      awk -v test="hello gawk" 'BEGIN{print test}' (相当于awk 'BEGIN{test="hello gawk";print test}')
    • 打印输出
      • print
        print item1,item2,...
    示例:
    tail -5 /etc/fstab | awk '{print $2,$4}' ($1..$#:内置变量,表示分隔后的字段)
    tail -5 /etc/fstab | awk '{print "hello:",$2,$4}' (注意,{}只能由单引号'' 引起来,不能用双引号"")
    要点:
        (1) 逗号,作为不同字段的分隔符;
        (2) item可以是字符串,数值,当前记录的字段、变量或awk的表达式;
        (3) 如省略item,相当于print $0(打印所有元素;$0表示所有字段)
      • printf
    格式化输出:printf FORMAT,item1,item2,...
    释义:
    (1) FORMAT必须给出;
    (2) 不会自动换行,需要显式给出换行控制符,'
    ';
    (3) FORMAT中需要分别为后面的每个item指定一个格式化符号;
            格式符:
                    %c:显示字符的ASCII码;
                    %d,%i:显示十进制整数;
                    %e,%E:科学计数法数值显示;
                    %f:显示为浮点数;
                    %g,%G:以科学计数法或浮点形式显示数值;
                    %s:显示字符串;
                    %u:无符号整数;
                    %%:显示%自身
            修饰符:
                    #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度
    示例:
      %-3.1f,其中 '-' 表示左对齐;%+5.2d,其中 '+' 会显示数值的符号
      awk -F: '{printf "Uername:%s, UID:%d
    ",$1,$3}' /etc/passwd
      awk -F: '{printf "Uername:%-15s, UID:%d
    ",$1,$3}' /etc/passwd
    •  操作符
      算术操作符:x+y,x-y,x*y,x/y,x^y(多少次方),x%y
      赋值操作符:=,+=,-=,*=,/=,%=,^=,++,--
      比较操作符:>,>=,<,<=,!=,==
      模式匹配符:~:是否匹配;!~:是否不匹配
      逻辑操作符:&&,||,!
      函数调用:function_name(argu1,argu2,...)
      条件表达式:selector ? if-true-expression : if-false-expression
    示例:
      awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s : %-s
    ",$1,usertype}' /etc/passwd
      awk '!/^UUID/{print $0}' /etc/fstab
      awk -F: '$3>1000{print $1,$3}' /etc/passwd
      awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd
    • PATTERN
    (1) /regular expression/:仅处理被模式匹配到的行;
    (2) relational expression:关系表达式,为"真"时处理 ("真":结果是非0值或非空字符串);
    (3) line ranges:行范围 (startline, endline 或 /pat1/, /pat2/);
        注意: 此处行范围不支持直接给出数字的格式
        示例:
      awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
      awk -F: '/^h/,/^s/{print $1}' /etc/passwd (4) BEGIN/END模式: BEGIN{}: 仅在开始处理文件中的文本之前执行一次; END{}:仅在文本处理完成之后执行一次 示例:
      head /etc/passwd | awk -F: 'BEGIN{print "username uid"}{printf "%-12s%-5s ",$1,$3}END{printf "%10s ","END"}'
    • 控制语句
      • if-else
    语法:
        if(condition) statement [else statement]
    使用场景:
        对awk取得的整行或某个字段做条件判断.
    示例:
        awk -F: '{if($3>=1000) {printf "Common user: %s
    ",$1} else {printf "root or Sysuser: %s
    ",$1}}' /etc/passwd
        awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
        awk '{if(NF>5) print $0}' /etc/fstab
        df -h | awk -F% '/^/dev/{print $1}' | awk '{if($NF>=20) print $1}'
      • while and do while
    语法:
        while(condition) statement (条件"真"时进入循环;条件"假"时退出循环)
        do statement while(condition) (至少执行一次循环体)
    使用场景:
        对一行内的多个字段逐一处理时使用;对数组中的各元素逐一处理时使用.
    示例:
        awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
        awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg
      • for
    语法:
        for(expr1;expr2;expr3) statement
        for(variable assignment;condition;iteration process) {for-body}
    示例:
        awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
    特殊用法:遍历数组中的元素
        语法:for(var in array) {for-body}
      • switch
    语法:
        switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; ...; default: statement}
      • break and continue
    break:终止循环
    continue:中断本次循环继续下一轮
      • next
    提前结束对本行的处理而直接进入下一行;
    示例:
        awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
    • array数组
    1) 关联数组:
        array[index-expression]
        index-expression:
            ① 可使用任意字符串;字符串要使用双引号;
            ② 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为"空串"
    2) 若要判断数组中是否存在某元素,要使用"index in array"格式进行;
    3) 若要遍历数组中的每个元素,要使用for循环:for(var in array) {for-body}
    示例:
        awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'
        netstat -tan | awk '/^tcp>/{state[$NF]++}END{for(i in state){ print i,state[i]}}'
        awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log
        awk '/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab
        awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab
        netstat -tan | awk '/^tcp>/{state[$NF]++}END{for(i in state){print i,state[i]}}'
    • 内置函数
        rand():返回0和1之间一个随机数;
        length([s]):返回指定字符串的长度;
        sub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容;
        gsub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其所有出现均替换为s所表示的内容;
        split(s,a,[r]):以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中
    示例:
        netstat -tan | awk '/^tcp>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
        awk '/^[[:space:]]*kernel/{i=1;while(i<=NF){if(length($i)>=7)print $i,length($i);i++}}' /etc/grub.conf
  • 相关阅读:
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    PHP serialize() 函数
    PHP print_r() 函数
  • 原文地址:https://www.cnblogs.com/walk1314/p/9077590.html
Copyright © 2011-2022 走看看