zoukankan      html  css  js  c++  java
  • linux awk

        • which awk
        • ll /usr/bin/awk
        • centOS系统默认使用的是gawk



    基本用法:
        • awk [options] ‘program’ var=value file…
            ○ options 选项;program 程序
        • awk [options] -f programfile var=value file…
            ○ -f prografile 程序比较复杂,可以写到文件中进行调用
        • awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file …
            
        • awk 程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块,共3部分组成
        • program通常是被单引号或双引号中
    选项:
        • -F 指明输入时用到的字段分隔符
        • -v var=value: 自定义变量


    基本格式:awk [options] 'program' file…
    program:pattern{action statements;..}
    pattern和action:
        •pattern部分决定动作语句何时触发及触发事件
            BEGIN:还没进行文件操作时做的操作(如表头)
            END:文件操作之后,做的操作(如汇总)
        •action statements对数据进行处理,放在{}内指明
            print, printf
    分割符、域和记录
        •awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。$0为所有域。注意:和shell中变量$符含义不同
        •文件的每一行称为记录
        •省略action,则默认执行 print $0 的操作

    示例:
        • awk '{print "hello,awk"}'  等待键盘输入,打印
        • awk 'BEGIN{print "hello"}' 打印一次hello
        • awk -F: '{print $1,$3}'/etc/passwd冒号分割,打印第一个和第三个字段
        • awk -F: '{print $1" "$3}'/etc/passwd 打印时,指定 为分隔符
        • awk -F: '{print $1" "$3}'/etc/passwd 打印时,第一个字段和第二个字段换行
        • df | awk '{print $5}' awk默认空格为分隔符,打印分区利用率
        • df | awk '{print "dev use% is "$5}' "dev use% is "为说明性文字
        • awk –F: '{print}' /etc/passwd  -F:指定分隔符为冒号
        • awk –F: ‘{print “wang”}’ /etc/passwd
        • awk –F: ‘{print $1}’ /etc/passwd
        • awk –F: ‘{print $0}’ /etc/passwd
        • awk –F: ‘{print $1” ”$3}’ /etc/passwd
        • tail –3 /etc/fstab |awk ‘{print $2,$4}’

    内置变量
    FS:输入字段分隔符,默认为空白字符
        • awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd 文件分隔符变量FS,更加灵活
        • awk –F: '{print $1,$3,$7}’ /etc/passwd
    OFS:输出字段分隔符,默认为空白字符
        • awk -v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd
    RS:输入记录分隔符,指定输入时的换行符(指定换行分隔符)
        • awk -v RS=' ' ‘{print }’ /etc/passwd
    ORS:输出记录分隔符,输出时用指定符号代替换行符
        • awk -v RS=' ' -v ORS='###'‘{print }’ /etc/passwd
    NF:字段数量(统计每行有几个字段)$NF表示最后一个字段、$NF-1表示倒数第二个字段
        • awk -F: ‘{print NF}’ /etc/fstab,引用内置变量不用$
        • awk -F: '{print $(NF-1)}' /etc/passwd
    NR:记录号(记录的编号)
        • awk -F: '{print NR,$NF}' /etc/fstab
        • awk END'{print NR}' /etc/fstab
    FNR:各文件分别计数,记录号
        • awk '{print FNR}' /etc/fstab /etc/inittab FNR分开显示文件的编号
    FILENAME:当前文件名
        • awk '{print FILENAME}’ /etc/fstab
    ARGC:awk命令行参数的个数,awk本身也算作参数
        • awk '{print ARGC}’ /etc/fstab /etc/inittab
        • awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab
    ARGV:参数数组,保存的是命令行所给定的各参数
        • awk ‘BEGIN {print ARGV[0]}’ /etc/fstab /etc/inittab
        • awk ‘BEGIN {print ARGV[1]}’ /etc/fstab /etc/inittab

    自定义变量

    自定义变量(区分字符大小写)
    (1) -v var=value
    (2) 在program中直接定义
    示例:
        • awk -v test='hello gawk' '{print test}' /etc/fstab 从fstab文件没读入一行,打印一次自定义变量test
        • awk -v test='hello gawk' 'BEGIN{print test}'
        • awk 'BEGIN{test="hello,gawk";print test}' 在大括号里面赋值
        • awk '{pirnt test;test="test awk"}' /etc/fstab 第一次读取fstab后,test因为没有赋值所以打印为空
        • awk –F:‘{sex=“male”;print $1,sex,age;age=18}’ /etc/passwd
        • cat awkscript awk代码放到文件中
            ○ awk –F: -f awkscript  /etc/passwd -f调用awk文件

    printf命令 不会自动换行

    格式化输出:printf “FORMAT”, item1, item2, ...
        • (1) 必须指定FORMAT
        • (2) 不会自动换行,需要显式给出换行控制符,
        • (3) FORMAT中需要分别为后面每个item指定格式符
    格式符:与item一一对应
        • %c: 显示字符的ASCII码
        • %d, %i: 显示十进制整数
        • %e, %E:显示科学计数法数值
        • %f:显示为浮点数
        • %g, %G:以科学计数法或浮点形式显示数值
        • %s:显示字符串
        • %u:无符号整数
        • %%: 显示%自身
    修饰符:
        • #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
        • -: 左对齐(默认右对齐) %-15s 字符串占位15个字符,不够15个左对齐
        • +:显示数值的正负符号 %+d

    举例
        •awk -F: ‘{printf "%s ",$1}’ /etc/passwd 格式为打印第一个字段(字符串)后,换行
            ○ awk -F: ‘{printf "%s:%d ",$1,$3}’ /etc/passwd 第一个字段(字符串)和第二个字段(整数)用冒号隔开
        •awk -F: ‘{printf "%s ",$1}’ /etc/passwd
        •awk -F: '{printf "%-20s %-10d ",$1,$3}' /etc/passwd 第一个字段宽度左对齐20宽度
            ○ awk -F: 'BEGIN {print "username userid" }{printf "%-20s %-10d ",$1,$3}' /etc/passwd 添加表头
            ○ awk -F: 'BEGIN {print "username userid ------------------" }{printf "%-20s | %-10d ",$1,$3}' /etc/passwd 添加分割线
        •awk -F: ‘{printf "Username: %s ",$1}’ /etc/passwd
        •awk -F: ‘{printf “Username: %s,UID:%d ",$1,$3}’
        /etc/passwd
        •awk -F: ‘{printf "Username: %15s,UID:%d ",$1,$3}’
        /etc/passwd
        •awk -F: ‘{printf "Username: %-15s,UID:%d ",$1,$3}’
        /etc/passwd

    运算符

    算术操作符:
        • x+y, x-y, x*y, x/y, x^y, x%y
        • -x: 转换为负数
        • +x: 转换为数值
    字符串操作符:没有符号的操作符,字符串连接
    赋值操作符:
        • =, +=, -=, *=, /=, %=(取模-取余数), ^=
        • ++, --
    下面两语句有何不同
        •awk ‘BEGIN{i=0;print ++i,i}’ 结果:1、1
        •awk ‘BEGIN{i=0;print i++,i}’ 结果:0、1
    比较操作符:
        • ==, !=, >, >=, <, <=
    模式匹配符:
        • ~:左边是否和右边匹配包含
        •  !~:是否不匹配
    示例:
        • awk –F: '$0 ~ /root/{print $1}‘ /etc/passwd $0是否包含root
        • awk '$0 ~“^root"' /etc/passwd 不写{print $0},默认
        • awk '$0 !~ /root/‘ /etc/passwd
        • df | awk '$1 ~ /^/dev/sd/{print $1,$5}' 匹配磁盘($1 ~ /^/dev/sd/),打印分区和磁盘利用率
        • df | awk '$1 ~ /^/dev/sd/{print $1,$5}' | awk -F% 'print $1' 去掉百分号
        • df | awk '$1 ~ /^/dev/sd/{print $1,$5}' | awk -F% 'print $1' | awk '$2 >10 {print $1}' 分区利用率大于10报警
        • awk –F: ‘$3==0’ /etc/passwd 第三个字段等于0
    逻辑操作符:与&&,或||,非!
    示例:
        •awk –F: '$3>=100 && $3<=1000 {print $1}' /etc/passwd 大于100且小于1000
        •awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd 或关系
        •awk -F: ‘!($3==0) {print $1}' /etc/passwd 取反
        •awk -F: ‘!($3>=500) {print $3}’ /etc/passwd
            ○ 非零、非空,取反为0(假);非空、非零(真)
    函数调用: 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

    PATTERN:根据pattern条件,过滤匹配的行,再做处理
    (1)如果未指定:空模式,匹配每一行
    (2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来 //之间写正则表达式
            ○ awk -F: '/bash$/{print $1}' /etc/passwd 打印所有bash结尾的行
        • awk '/^UUID/{print $1}' /etc/fstab 打印所有UUID开头的行
        • awk '!/^UUID/{print $1}' /etc/fstab 非UUID开头的行
    (3) relational expression: 关系表达式,结果为“真”才会被处理
        • 真:结果为非0值,非空字符串
        • 假:结果为空字符串或0值
    示例:
        •awk -F: 'i=1;j=1{print i,j}' /etc/passwd
        •awk ‘!0’ /etc/passwd ; awk ‘!1’ /etc/passwd
        •awk –F: '$3>=1000{print $1,$3}' /etc/passwd
        •awk -F: '$3<1000{print $1,$3}' /etc/passwd
        •awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
        •awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd

    4) line ranges:行范围
        • awk -F: '/^lp/,/^ftp/{pirnt $1,$3}' /etc/passwd 以lp开头,到ftp开头的内容
        • startline,endline:/pat1/,/pat2/ 不支持直接给出数字格式
        • awk -F: ‘/^root>/,/^nobody>/{print $1}' /etc/passwd
        • awk -F: ‘(NR>=10&&NR<=20){print NR,$1}' /etc/passwd NR行号表示获取范围
    (5) BEGIN/END模式
        • BEGIN{}: 仅在开始处理文件中的文本之前执行一次
        • END{}:仅在文本处理完成之后执行一次
            ○ awk 'NR>=10 && NR<==20{pirnt NR, $0}END{print "finished"}' /etc/passwd


    •awk -F : 'BEGIN {print "USER USERID"} {print $1":"$3} END{print "end file"}' /etc/passwd
    •awk -F : '{print "USER USERID“;print $1":"$3} END{print "end file"}' /etc/passwd
    •awk -F: 'BEGIN{print " USER UID --------------- "}{print $1,$3}' /etc/passwd
    •awk -F: 'BEGIN{print " USER UID --------------- "}{print $1,$3}'END{print "=============="} /etc/passwd
    •seq 10 |awk ‘i=0’  假,不打印
    •seq 10 |awk ‘i=1’  真,打印
    •seq 10 | awk 'i=!i‘ 打印奇数行
    •seq 10 | awk '{i=!i;print i}‘  
    •seq 10 | awk ‘!(i=!i)’ 打印偶数行
    •seq 10 |awk -v i=1 'i=!i'


    常用的action分类
    •(1) Expressions:算术,比较表达式等
    •(2) Control statements:if, while等
    •(3) Compound statements:组合语句
    •(4) input statements
    •(5) output statements:print等


    { statements;… } 组合语句
    if(condition) {statements;…}
    if(condition) {statements;…} else {statements;…}
    while(conditon) {statments;…}
    do {statements;…} while(condition)
    for(expr1;expr2;expr3) {statements;…}
    break
    continue
    delete array[index]
    delete array
    exit


    语法:if(condition){statement;…}{else statement}
    if(condition1){statement1}else if(condition2){statement2}
    else{statement3}
    使用场景:对awk取得的整行或某个字段做条件判断
    示例:
        • awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
        • awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
        • awk '{if(NF>5) print $0}' /etc/fstab
        • awk -F: '{if($3>=1000) {printf "Common user: %s ",$1} else {printf "root or Sysuser: %s ",$1}}' /etc/passwd
        • awk -F: '{if($3>=1000) printf "Common user: %s ",$1;
        • else printf "root or Sysuser: %s ",$1}' /etc/passwd
        • df -h|awk -F% '/^/dev/{print $1}'|awk '$NF>=80{print $1,$5}‘  $NF表示最后一个字段
        • df -h|awk -F% '/^/dev/{print $1}'|awk '{if($NF>=80)print $1,$5}‘
        • awk 'BEGIN{ test=100;if(test>90){print "very good"} else if(test>60){ print "good"}else{print "no pass"}}'


    while循环
    语法:while(condition){statement;…}
    条件“真”,进入循环;条件“假”,退出循环
    使用场景:
    对一行内的多个字段逐一类似处理时使用
    对数组中的各元素逐一处理时使用
    示例:
        • 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)>=10) {print $i,length($i)}; i++}}' /etc/grub2.cfg 字段长度大于10,进行打印

        • awk 'BEGIN {print lenth("abc")}'  打印字符长度,结果为3
        • awk -F: '{i=1;while(i<=NF){print $i, lenth($i); i++}}' /etc/passwd  打印每行中每个字段及其长度
        • awk -F: 'NR<=3 {i=1;while(i<=NF){print $i, lenth($i); i++}}' /etc/passwd 打印前三行中每个字段及其长度

    do-while循环
    语法:do {statement;…}while(condition)
    意义:无论真假,至少执行一次循环体
    示例:
    •awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}‘
        • awk 'BEGIN{sum=0;i=1;while(i<=100){sum+=i;i++;print "sum="sum}}' 1加到100
        • echo {1..100} | tr ' ' '+' | bc 1加到100
        • seq -s"+" 100 | bc 1加到100


    for循环
    语法:for(expr1;expr2;expr3) {statement;…}
    常见用法:
    for(variable assignment;condition;iteration process)
    {for-body}
    特殊用法:能够遍历数组中的元素
    语法:for(var in array) {for-body}
    示例:
        • awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
        • awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}' 1加到100
        • awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==50)continue;sum+=i};print sum}' i=50时跳出循环
        • awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==50)break;sum+=i};print sum}'  i=50时结束循环

    next:
    提前结束对本行处理而直接进入下一行处理(awk自身循环)
        • awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd 结束本行计算
        • awk -F: 'NR<=3{i=1;while(i<NF){if(i==4)next;print $i,length($i);i++}}' 统计三行(NR),如果第四个字段(NF)就不打印了
        
        
    数组

    若要遍历数组中的每个元素,要使用for循环
    for(var in array) {for-body}
    注意:var会遍历array的每个索引
    示例:
    •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 '{ips[$1]++}END{for(ip in ips){print ip, ips[ip]}}' /var/log/httpd/access_log 每个ip地址连接了多少次
    •awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

        • awk 'BEGIN{titles["ceo"]="mage";titles["coo"="zhang"];for(i in titles){print i " is "titles[i]}}' 打印顺序不确定


    函数

    数值处理:
    rand():返回0和1之间一个随机数 srand()先执行,rand()才有种子
    awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }' 整数随机数
    字符串处理:
    •length([s]):返回指定字符串的长度
    •sub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换为s
    echo "2008:08:08 08:08:08" | awk 'sub(/:/,“-",$1)' 搜索问号,用冒号代替,只替代一个
    •gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
    echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,“-",$0)'  搜索问号,用冒号代替
    •split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…
    netstat -tan | awk '/^tcp>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'

  • 相关阅读:
    jquery animate()方法 语法
    jquery unload方法 语法
    jquery undelegate()方法 语法
    jquery unbind()方法 语法
    jquery trigger() 方法 语法
    jquery toggle()方法 语法
    jquery change() 函数 语法
    jquery blur()函数 语法
    jquery bind()方法 语法
    jquery checked选择器 语法
  • 原文地址:https://www.cnblogs.com/lizitest/p/9552930.html
Copyright © 2011-2022 走看看