zoukankan      html  css  js  c++  java
  • awk基本用法

    awk 是一种编程语言,用于在 linux/unix 下对文本和数据进行处理。
    awk 数据可以来自标准输入、一个或多个文件,或其它命令的输出。
    awk 通常是配合脚本进行使用, 是一个强大的文本处理工具。

    toc

    awk基本知识

    awk 的两种形式语法格式

    awk [options] 'commands' filenames
    awk [options] -f awk-script-file filenames
    options
    -F 定义输入字段分隔符,默认的分隔符是空格或tab键(就是改变内部变量 FS,FS 来确定字段分隔符)
    OFS 是另一个内部变量,用来定义输出字段分隔符的。比如 $1,$3 之间有个逗号,之后输出内容之间变为空格,是因为 OFS 默认为空格
    
    command
    BEGIN{}            {}                END{}
    行处理前        行处理        行处理后

    awk命令格式

    ## awk 匹配文件带root的行
    [root@Shell ~]# awk '/root/' /etc/passwd
    ## awk 对文件行进行动作处理(以冒号为字段分隔符,打印第一个字段)
    [root@Shell ~]# awk -F: '{print $1}' /etc/passwd
    ## awk 匹配文件 + 处理动作
    [root@Shell ~]# awk -F ':' '/root/ {print $1,$3}' /etc/passwd
    [root@Shell ~]# awk 'BEGIN{FS=":"} /root/{print $1,$3}' /etc/passwd
    ## awk 匹配结尾为 / 的行,第三个字段大于50000则打印第四个字段
    [root@Shell ~]# df |awk '//$/ {if ($3>50000) print $4}'

    awk内部变量

    $0 所有内容

    ## 打印文件的所有内容
    [root@Shell ~]# awk '{print $0}' /etc/passwd

    NR 控制输入的总行数

    ## 打印文件行号
    [root@Shell ~]# awk '{print NR,$0}' /etc/passwd
    ## 打印文件的前三行
    [root@Shell ~]# awk 'NR<=3' /etc/passwd

    FNR 记录输入文件行号(当读取多个文件FNR会从零开始计算行号,NR则不会)

    ## 打印文件行号
    [root@Shell ~]# awk '{print FNR,$0}' /etc/passwd
    ## 打印第十行内容
    [root@Shell ~]# awk 'NR==10{print $0}' /etc/passwd

    NF 记录行的最后一分段内容

    ## 打印每一行最后一个分段
    [root@Shell ~]# awk -F ":" '{print $NF}' /etc/passwd
    ## 打印文件总分段
    [root@Shell ~]# awk '{print NF,$0}' /etc/passwd

    FS 指定字段分割符,默认空格

    ## 以冒号作为字段分隔符
    [root@Shell ~]# awk -F: '/root/{print $1, $3}' /etc/passwd
    [root@Shell ~]# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd
    ## 以空格冒号 tab 作为字段分割
    [root@Shell ~]# awk -F'[ :	]' '{print $1,$2,$3}' /etc/passwd

    OFS 输出字段分隔符

    ## 以冒号为输出分隔符,匹配开始为root的行,输出一二三分段,输出分段之间以+++间隔
    [root@Shell ~]# awk -F ':' 'BEGIN{OFS="+++"} /^root/{print $1,$2,$3}' /etc/passwd
    root+++x+++0

    RS 输入记录分隔符,awk是根据 RS 来定位检索断点的。因为 RS 默认换行符( ),所有awk默认是逐行来检索

    ## 提取下面三个域名
    [root@Shell ~]# echo '<a href="www.songguoyou.com">宋国友</a><a href="www.baidu.com">百度</a><a>href="www.taobao.com">淘宝</a>'  > link.txt
    ## 以 </a> 划分行
    [root@Shell ~]# awk 'BEGIN{RS="</a>"}{print NR,$0}' link.txt
    1 <a href="www.songguoyou.com">宋国友
    2 <a href="www.baidu.com">百度
    3 <a href="www.taobao.com">淘宝
    4 
    ## 用 NF>0 来排除空行(删除所有 NF=0 的分段)
    [root@Shell ~]# awk 'BEGIN{RS="</a>"}NF>0{print NR,$0}' link.txt
    1 <a href="www.songguoyou.com">宋国友
    2 <a href="www.baidu.com">百度
    3 <a href="www.taobao.com">淘宝
    ## 最后以双引号为分隔符打印第二个分段
    [root@Shell ~]# awk 'BEGIN{RS="</a>"}NF>0{print $0}' link.txt |awk 'BEGIN{FS="""}{print $2}'
    www.songguoyou.com
    www.baidu.com
    www.taobao.com

    ORS 输出记录分隔符,和RS原理一样,就是作用在输出上了

    ## 输出时候把所有换行符替换成 | 
    [root@Shell ~]# awk 'BEGIN{ORS="|"}{print $0}' /etc/sysconfig/network-scripts/ifcfg-eth0
    TYPE=Ethernet|PROXY_METHOD=none|BROWSER_ONLY=no|BOOTPROTO=static|DEFROUTE=yes|IPV4_FAILURE_FATAL=no|IPV6INIT=yes|IPV6_AUTOCONF=yes|IPV6_DEFROUTE=yes|IPV6_FAILURE_FATAL=no|IPV6_ADDR_GEN_MODE=stable-privacy|NAME=ens33|UUID=34e475e4-12a1-4c0f-bdaa-68b467ea9c44|DEVICE=eth0|ONBOOT=yes|IPADDR=192.168.1.1|[root@Shell ~]# 

    print 格式化输出函数

    [root@Shell ~]# date|awk -F '[ :]' '{print "当前时间:",$NF,"年",$2,"月",$3,"日""
    ",$4,"小时",$5,"分",$6,"秒"}'
    ## printf 函数
    [root@Shell ~]# awk -F: '{printf "%-15s %-10s %-15s
    ", $1, $2, $3}' /etc/passwd
    %c: 显示字符的ASCII码;
    %d, %i: 显示十进制整数;
    %e, %E: 科学计数法数值显示;
    %f:显示为浮点数;
    %g, %G:以科学计数法或浮点形式显示数值;
    %s:显示字符串;
    %u:无符号整数;
    %%: 显示%自身;
    占 15 字符
    - 表示左对齐,默认是右对齐
    printf 默认不会在行尾自动换行,加
    

    awk模式动作

    awk语句都由模式和动作组成。
    模式部分决定动作语句何时触发及触发事件。
    如果省略模式部分,动作将时刻保持执行状态。
    模式可以是条件语句或复合语句或正则表达式

    使用正则表达式

    ## 匹配不以a、b、c、d为开头字母的行
    [root@Shell ~]# awk '!/^[a-d]/' /etc/passwd
    ## 匹配第五个分段为a字母开头并且nologin为结尾的行
    [root@Shell ~]# awk -F: '$5~/^a/&&/nologin$/' /etc/passwd

    使用比较表达式
    比较表达式使用关系运算符对数字与字符串进行比较,只有当条件为真,才执行指定的动作

    ## uid 为 0 的列出来
    [root@Shell ~]# awk -F ":" '$3==0' /etc/passwd
    ## uid 小于 10 的全部列出来
    [root@Shell ~]# awk -F: '$3 < 10' /etc/passwd
    ## 用户登陆的 shell 等于 /bin/bash
    [root@Shell ~]# awk -F: '$7 == "/bin/bash" ' /etc/passwd
    ## 第一列为 alice 的列出来
    [root@Shell ~]# awk -F: '$1 == "alice" ' /etc/passwd
    ## 为 alice 的用户列出来
    [root@Shell ~]# awk -F: '$1 ~ /alice/ ' /etc/passwd
    ## 磁盘使用率大于多少则,则打印可用的值
    [root@Shell ~]# df |awk '//$/'|awk '$3>1000000 {print $4}'

    运算表达式

    ## 第三个分段和第四个分段相加
    [root@Shell ~]# awk -F: '{print $3 + $4}' /etc/passwd
    ## 显示所有普通用户
    awk -F: 'BEGIN{OFS="--"} { if($3*10>=10000) {print $1,$3} }' /etc/passwd

    逻辑操作符和复合模式

    &&逻辑与         || 逻辑或         !逻辑非
    ## 匹配用户名为 root 并且 uid 小于 1 的行
    [root@Shell ~]# awk -F: '$1~/root/ && $3<=1' /etc/passwd
    ## 匹配用户名为 root 或 uid 大于 1000
    [root@Shell ~]# awk -F: '$1~/root/ || $3>=1000' /etc/passwd

    awk条件判断

    if语句格式:{ if(表达式){语句;语句;... }}

    ## 打印当前管理员用户名称
    [root@Shell ~]# awk -F: '{ if($3==0){print $1,"is adminisitrator"} }' /etc/passwd
    ## 统计系统用户数量
    [root@Shell ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd
    ## 统计普通用户数量
    [root@Shell ~]# awk -F: '{ if($3>1000){i++}} END {print i}' /etc/passwd

    if...else 语句格式: {if(表达式){语句;语句;... }else{语句;语句;...}}

    ## 如果 uid 等于 0 则打印用户名,否则打印 shell 环境变量
    [root@Shell ~]# awk -F: '{if($3==0){print $1} else {print $NF}}' /etc/passwd
    ## 打印管理员个数和系统用户个数
    [root@Shell ~]# awk -F: '{if($3==0){count++} else{i++}} END{print " 管理员个数: "count ; print "系统用户数: "i}' /etc/passwd

    {if(表达式 1){语句;语句;... }else if(表达式 2){语句;语句;. .. }else{语句;语句;... }}

    ## 统计管理员、系统用户和普通用户的个数
    [root@Shell ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print "管理员个数"i; print "系统用户个数" j; print "普通用户个数"k }' /etc/passwd

    awk循环语句

    while循环
    while(表达式){语句}

    ## 计算从1累加到100的值
    [root@Shell ~]# awk 'BEGIN{test=100;num=0;while(i<=test){num+=i; i++;}print num;}'

    for循环
    for(初始表达式;终止条件;步长表达式){语句}

    ## 计算从1累加到100的值
    [root@Shell ~]# awk 'BEGIN{test=0;for(i=0;i<=100;i++){test+=i;}print test;}'

    do-while循环
    do{语句}while(条件判断语句)

    ## 计算从1累加到100的值
    [root@Shell ~]# awk 'BEGIN{test=0;i=0;do{test+=i;i++}while(i<=100)print test;}'

    awk数组

    [root@Shell ~]# awk -F: '{username[i++]=$1} END{print username[1]}' /etc/passwd

    按索引遍历

    ## 遍历所有用户并打印
    [root@Shell ~]# awk -F: '{username[j++]=$1}END{for(i in username){print i,username[i]}}' /etc/passwd
    ## 统计 /etc/passwd 中各种类型 shell 的数量
    [root@Shell ~]# awk -F: '{shells[$NF]++}END{for(i in shells){print i,shells[i]}}' /etc/passwd
    ## 网站访问状态统计
    [root@Shell ~]# ss -an|awk '/:80/{tcp[$2]++}END{for(i in tcp){print i,tcp[i]}}'
    ## 统计当前访问的每个IP的数量
    [root@Shell ~]# ss -an|awk -F ':' '/:80/{ips[$(NF-1)]++} END {for(i in ips){print i,ips[i]}}'
  • 相关阅读:
    财务报表分析(张新民教授)-第七章 企业财务质量分析
    财务报表分析(张新民教授)-第七章 企业财务质量分析
    财务报表分析(张新民教授)-第七章 企业财务质量分析
    财务报表分析(张新民教授)-第七章 企业财务质量分析
    财务报表分析(张新民教授)-第七章 企业财务质量分析
    财务报表分析(张新民教授)-第七章 企业财务质量分析
    PS
    史上最强视频网站真实地址解析
    jsonp详解
    width:100%缩小窗口时背景图片出现空白bug
  • 原文地址:https://www.cnblogs.com/songguoyou/p/11884294.html
Copyright © 2011-2022 走看看