zoukankan      html  css  js  c++  java
  • shell脚本 awk工具

    awk工具概述
    awk编程语言/数据处理引擎
    基于模式匹配检查输入文本,逐行处理并输出
    通常在shell脚本中,或取指定的数据
    单独用时,可对文本数据做统计

    命令格式
    格式一:awk [选项] '[条件]{编辑指令}' 文件
    格式二:前置命令 | awk [选项] '[选项]{编辑指令}'

    常用命令选项:
    -F:指定分隔符,可省略(默认空格或tab位)
    -f:调用awk脚本进行处理
    -v:调用外部shell变量

    实例:
    [root@ceshiji ~]# awk '{print $1}' /etc/passwd
    [root@ceshiji ~]# awk -F: '{print $1}' /etc/passwd

    awk内置变量
    变量 用途
    FS 保存或设置字段分隔符,例如 FS=":"
    $n 指定分隔得第n个字段,如$1,$3分别表示第1,第3列
    $0 一整行
    NF 记录当前处理行的字段列数
    NR 当前行号
    FNR 当前行在源文件中的行号
    FILENAME 当前处理的文件名
    ENVIRON 调用shell环境变量,格式:ENVIRON["变量名"]
    awk自定义变量:awk 'BEGIN{name="hydra";x=101;print name,x}'
    调用shell变量:
    -v:调用shell自定义变量,调用shell系统环境义变量

    实例:
    [root@ceshiji ~]# awk '/Failed/{print $11}' /var/log/secure |uniq -c(统计本机被攻击次数)

    awk过滤的时机:
    (可单独使用,也可以同时一起使用)

    awk执行过程:
    行前处理:把数据的初始化操作,写在行前处理
    BEGINE{ }

    逐行处理:对每一行都处理
    { }

    行后处理:做总结性输出
    END{ }

    awk语法格式:
    awk 选项 ""文件列表
    awk 选项 '条件{ }' 文件列表
    awk 'BEGINE{ }{ }END{ }' 文件


    实例:
    [root@ceshiji ~]# awk 'BEGIN{a=34;print a+12}'(预处理不需要数据文件)
    [root@ceshiji ~]# awk 'BEGIN{x=0}/<bash>$/{x++}END{print x}' /etc/passwd(统计bash用户个数)

    条件的表现形式:
    正则表达式
    数值/字符串比较
    逻辑比较
    运算符

    正则表达式
    数据 符号 /正则表达式/(正则符号:. * $ ^ [] { }() ^[] [^ ] ? + > )
    匹配:~
    不匹配:!~
    [root@ceshiji ~]# awk -F: '/^ro/{print}' /etc/passwd(匹配以ro开头的用户记录)
    [root@ceshiji ~]# awk -F: '$7!~/bash$/{print $1,$7}' /etc/passwd(匹配第7个字段不以bash结尾的用户名登陆shell)

    字符/数值比较
    ==:等于
    !=:不等
    >:大于
    >=:大于等于
    <:小于
    <=:小于等于
    数据 符号 "字符串"

    [root@ceshiji ~]# awk 'NR==2{print}'a.txt(输出第二行文本)
    [root@ceshiji ~]# awk '$2="xx"{print}'a.txt(输出第二列不是xx的行)
    [root@ceshiji ~]# awk 'NF>=2{print}'a.txt(输出包含2个及以上字段的行)
    [root@ceshiji ~]# awk 'NR >=5 && NR<=10{print FNR,$0}' /etc/passwd(输出文件中的5-10行)

    逻辑比较测试
    &&:期望多个条件都成立
    ||:只要有一个条件成立即满足要求
    [root@ceshiji ~]# awk -F: '$3>=0&&$3<2{print$1,$3}'/etc/passwd(列出uid小于2的用户信息)

    运算符
    + - * / %
    ++ -- += -= *= /=
    [root@ceshiji ~]# awk 'NR%2==0{print NR,$0;i++}'END{print i}' /etc/paswd(输出偶数行的内容,并统计个数)
    [root@ceshiji ~]# seq 31 69 | awk '$0%7==0||$0~/7/{print $0;i++}END{print i}'(输出31-69之间包含7或者7的倍数的数,并统计)

    综合实例:
    根据/etc/passwd提取密码串
    找到使用bash作登陆shell的本地用户
    列出这些用户的shadow密码记录
    按每行 用户名——》密码记录 保存结果
    #!/bin/bash
    user=`awk -F '/bash$/s/:.*//p' /etc/passwd`
    for i in $user
    do
    awk -F: -v x=$i '$1==x{print $2}' /etc/shadow
    echo "$ipass$pass"
    done

    ——————————————————————————————————————————————————
    awk和shell的区别:
    shell:if[];then
    命令
    else
    fi

    awk:if(END){命令}
    else {命令}

    awk流程控制
    分支结构:
    单分支
    if(条件){执行命令}
    双分支
    if(条件){执行命令1}else{执行命令2}
    多分支
    if(条件){执行命令1}else if(条件){执行命令2}else{执行命令N}

    实例:
    统计uid大于或等于500的用户个数:
    [root@ceshiji ~]# awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}}else{j++}}END{print i,j}' /etc/passwd
    统计内建个数和外键用户个数:
    [root@ceshiji ~]# awk 'BEGIN{FS=":";i=0;j=0;z=0}{z++}{if($3<500){i++}else{j++}}END{print "inside user is "i;print "outside user is"j;print "sum user is"z}' /etc/passwd
    闲长可以写为脚本下次直接调用
    #!/bin/awk -f
    BEGIN{FS=":";i=0;j=0;z=0}
    {z++}
    {
    if($3<500){
    i++}
    else{
    j++}}
    END{
    print "inside user is "i
    print "outside user is"j
    print "sum user is"z
    }

    循环结构
    while循环:
    while(条件){执行命令}

    do while循环:
    do{执行命令}while(条件)

    示例:
    统计/etc/passwd文件内root出现次数,利用-F[:/]表示分隔符为:或者/
    [root@ceshiji ~]# awk -F"[:/]" '{i=1;while(i<=NF){if($i="root"){j++}i++}}' /etc/passwd
    输出1-10的数:
    awk 'BEFIN{i=1;while(i<=10){print i;i++}}'(while循环)
    awk 'BEFIN{i=1;do{print i;i++}while(i<=10)}' (do while循环)

    for循环
    for(初值;条件;步长){执行命令}
    [root@ceshiji ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i}}'
    [root@ceshiji ~]# awk 'BEGIN{ for (i=1;i<=10;i++){ print i}}'(输出1-10的数)

    流程控制函数(控制循环结构的执行)
    关键字 含义
    break 结束当前的循环体
    continue 结束本次循环,转入下一次循环
    next 跳过当前行,让awk处理下一行
    exit 结束awk对数据的处理,如果有END{}的话执行其内的命令,如果没有则退出awk处理

    示例:
    awk 'BEGIN{for(i=1;i<=10;i++){if(i==3){break};print " "i}}'(i=3时结束循环)
    awk 'BEGIN{for(i=1;i<=5;i++){if(i==1||i==3){continue};print " "i}}'(不输出1和3)
    awk 'FNR==9{next}{print FNR,$1}' a.txt(到了第9行跳过,处理下一行)
    awk 'BEGIN{print NR}{print NR,FNR,$0}END{print NR}'a.txt
    awk 'FNR==6{exit}{print FNR,$0}END{print NR}' a.txt(处理到行号为6的时候,再处理END里面的内容)

    ——————————————————————————————————————————————————————
    awk数组

    数组的定义及使用
    定义数组
    格式:数组名[下标]=值(下标和值可以用数字和字符,下标和值是字符时要用""号)
    使用数组
    格式:数组名[下标]
    输出数组元素:
    格式: print 数组名[下标]

    示例:为数组name赋值两个元素,值分别为jim,tom
    [root@ceshiji ~]# awk 'BEGIN{name[0]="jim";name[1]="tom";print name[0],name[1]}'

    示例:把网段192.168.1.0/24ip地址保存到数组ipgrp里,然后把前十个ip输出
    [root@ceshiji ~]# awk 'BEGIN{for(i=1;i<=254;i++){ipgrp[i]="192.168.1."i};j=1;while(j<=10){print ipgrp[j];j++}}'


    示例:用awk写出访问过我的ip地址及次数:
    [root@redhat ~]# awk '{ipgrp[$1]++}END{ for (ip in ipgrp){print ip,ipgrp }}' /etc/httpd/logs/access_log

    遍历数组的专属循环结构
    用法:for(变量 in 数组名){print 数组名[变量]}
    [root@ceshiji ~]# awk 'BEGIN{FOR(I=1;I<=5;I++){IPGRP[I]="1.1.1."i};for(x in ipgrp){print x,ipgrp[x]}}'
    [root@ceshiji ~]# head /etc/passwd |awk -F ":" '{usergrp[$1]=$3}END{for(j in usergrp){print j,usergrp[j]}}'
    [root@ceshiji ~]# awk '{agrp[$0]++}END{for(x in agrp){pirint x,agrp[x]}}' a.txx

    awk数组的经典应用
    去除文本的重复行
    用法:awk '!a[$0]++' fileame
    逐行分析,遇到重复行跳过
    实例:列出/etc/passwd中的登陆shell种类
    [root@ceshiji ~]# awk -F: '!a[$7]++{print $7}' /etc/passwd

    sort工具
    -n:按数字升序排列
    -k:针对指定的字段进行排序
    -r:反向排序

    ————————————————————————————————————————————————————————

  • 相关阅读:
    postgresql客户端连接错误的解决方法【转】
    在游戏开发中使用管理类的目的和作用
    Unity3D对象池
    yield的作用
    Unity延迟和重复调用方法
    Unity的Asset Store商店下载文件路径
    C#委托和事件详解
    C#一个关于委托和事件通俗易懂的例子
    C#委托和事件定义和使用
    C#委托和事件
  • 原文地址:https://www.cnblogs.com/Hydraxx/p/7306219.html
Copyright © 2011-2022 走看看