zoukankan      html  css  js  c++  java
  • awk

    awk:
    主要是类unix系统下对文本或者数据处理的一种工具;一种编程语言。支持自己的函数还支持用户自定义的函数和正则表达式。
    awk有两种模式:命令行模式 脚本模式
    命令模式:
    awk [options] 'commands' files
    选项:
    -F:自定义字段的分割符,默认的分割符是空格或者连续的空格
    -v:定义变量
    -f:指定awk的脚本文件
    命令:
    1、范围说明,正则表达式,awk的语句{语句1;语句2...}
    2、awk语句需要用分号隔开
    3、调用shell的变量需要用双引号引起来
    字段的分割和变量:
    $0 文件本身
    $1~$n:代表文件用分割符分割的第1~第n列(字段)
    NF:文件当前记录的字段数(列数)
    $NF:文件的最后一列
    $(NF-1):
    FNR/NR:行号----->变量
    FILENAME 文件名
    RS:换行符
    "...":打印字符串
    :制表符
    FS:指定分割符
    print:打印
    示例:
    第1行:
    root uid homedir shell
    # awk -F: '{print "第" NR "行:" RS $1,$3,$(NF-1),$NF}' passwd1
    awk -F: '{print $NF}' passwd1----->打印最后1行
    awk -F: '{print $(NF-1)}' passwd1----->打印倒数第2行
    awk -F: '{print $1,$3,$(NF-1),$NF}' passwd1----->打印第1,3,6,7行
    awk -F: '{print $1"的UID是:"$3}' passwd1----> $1的UID是$3(eg:root的UID是1)
    awk -F: '{print NF}' passwd1
    【awk -F: '{print "第"NR"行":"RS,$1,$3,$(NF-1),$NF}' passwd1】
    awk -F: '{print "第"NR"行:" RS,$1,$3,$(NF-1),$NF}' passwd
    awk -F: '{print $0}' passwd1
    awk -F: '{print FILENAME}' passwd1
    计算求和:
    for ((i=1;i<=5;i++));do echo $i;done|awk '{i+=$1};END{print i}‘
    for ((i=1;i<=5;i++));do echo $i;done|awk '{a+=$1};END{print a}'
    for ((i=1;i<=10;i+=2));do echo $i;done|awk '{a+=$1};END{print a}'
    1) 范围
    BEGIN{};{}
    END
    (1) USERNAME HOME_DIR SHELL
    root /root /bin/bash
    ...
    # awk 'BEGIN{FS=":"};{print "USERNAME HOME_DIR SEHLL" RS $1" ",$(NF-1)" ",$NF}' passwd1
    (2) USERNAME HOME_DIR SHELL
    **************************************
    # awk -F: 'BEGIN{print "USERNAME HOME_DIR SEHLL" RS "**************************************"};{print $1" ",$(NF-1)" ",$NF}' passwd1
    (3) **************BEGIN******************
    USERNAME HOME_DIR SHELL
    ...
    **************END********************
    # awk -F: 'BEGIN{print "**************BEGIN******************"}RS{print "USERNAME HOME_DIR SHELL" RS,$1" ",$(NF-1)" ",$NF};END{print"**************END********************"}' passwd1
    2)正则表达式
    == 等于
    != 不等于
    >
    <
    >=
    <=
    ~ 匹配于
    !~ 不匹配
    &&
    ||
    awk -F: '/root/{print $1}' passwd1
    awk -F: '/root/{print $1,$3,$NF}' passwd1--->将有root关键字的第1,3和最后一列打印
    awk -F: 'NR==1,NR==5{print $0}' passwd1---->将第1~5行打印
    awk -F: '/^root/,/^halt/{print $0}' passwd1---->将以root开头到以halt开头的行打印
    awk -F: '/^adm/,NR==5{print $0}' passwd1--->将以admi开头到第5行打印
    awk -F: '/^root/||/^sync/{print $0}' passwd1--->将以root开头或以sync开头的行打印
    awk -F: 'NR>=2 && NR<=8{print $0}' passwd1---->将第2~8行打印
    awk -F: 'NR==1,NR==10{print $0}' passwd1---->将第1~10行打印
    awk -F: 'NR==1 || NR==10{print $0}' passwd1---->将第1行或第10行打印
    awk -F: 'NR==1 && NR==10{print $0}' passwd1---->空
    课堂练习:
    1、打印可以登录操作系统的用户的所有信息
    *****************BEGIN********************
    *****************END**********************
    # awk -F: '$7~/bash/{print $0}' passwd
    # awk -F: '/bash$/{print $0}' passwd
    # awk -F: '$0~/bash/{print $0}' passwd
    # awk -F: 'BEGIN{print "*******BEGIN******"}$0 ~ /bash/{print $0};END{print "*********END*******"}' passwd
    【cat /etc/passwd|awk -F: '//bin/bash/{print $0}'| awk -F: 'BEGIN{print "*****************BEGIN********************"}RS{print $0};END{print "*****************END**********************"}' passwd】
    2、打印出系统中普通用户以下信息
    USERNAME UID HOME_DIR SHELL
    *********************************************
    *********************************************
    # awk -F: 'BEGIN{print "USERNAME UID HOME_DIR SHELL" RS "****************"};$7~/bash/{print $1" "$3" "$(NF-1)" "$NF};END{print "***********"}' passwd
    【awk -F: 'BEGIN{print "USERNAME UID HOME_DIR SHELL" RS"*********************************************"}RS{print $1,$3,$6,$7};END{print "*********************************************"}'】
    3、找出文件中以数字开头awk -F: '/^[0-9]/{print $0}'
    # awk '$0 ~ /^[0-9]/{print $0}'
    # awk '/^[0-9]/{print $0}'
    4、找出文件中以任意字母开头的
    awk -F: ‘/^[a-z]/print $0’
    5、使用awk打印出自己的ip地址、子网掩码和广播地址
    # ifconfig eth0|awk NR==2|awk -F '[ :]+' '{print $4RS$6RS$8}'
    ---->10.1.1.110
    10.1.1.255
    255.255.255.0
    截取IP 地址:
    # ifconfig eth0|awk 'NR==2{print $2}'|awk -F: '{print $2}'--->10.1.1.110
    ifconfig|awk 'NR==2{print $0}'|awk '{print $2}'|awk -F: '{print $2}'
    ifconfig|awk 'NR==2{print $0}'|awk '{print $3}'|awk -F: '{print $2}'
    ifconfig|awk 'NR==2{print $0}'|awk '{print $4}'|awk -F: '{print $2}'
    。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
    awk的循环控制:
    if语句:
    (1) {if(表达式) {语句1;语句2;...}}
    # awk -F: '{if($3==0){print $1,"admin"}}'
    # awk -F: '{if($3!=0){print $1,"not admin"}}' passwd1
    (2) {if(表达式) {语句1;语句2;...}else{语句1;语句2;...}}
    # awk -F: '{if ($3==0){print $1,"is administrator"}else{print $1,"is other user"}}'
    统计管理员,系统用户,普通用户的个数:
    # awk -F: '{if($3==0){count++}else{i++}};END{print "管理员个数:" count;print "其他用户的个数:" i}'
    # awk -F: '{if($3==0){i++}else if($3>=500 && $3!=65534){j++}else{x++}}END{print "管理员的个数为:"i;print "系统用户的个数为:"x;print "普通用户的个数为:" j}'
    (3) {if(表达式1){语句1;..}else if(表达式2){语句1;..}else{语句1;...}}
    if [xxx];then
    xxx
    elif [xxx];then
    xxx
    else
    fi
    # awk -F: '{if($3==0){print $1,"是管理员"}else if($3<500 || $3==65534){print $1,"是系统用户"}else{print $1,"是普通用户"}}'
    for循环:
    for ((i=1;i<=5;i++));do echo $i;done
    awk 'BEGIN{for(i=1;i<=5;i++) print i}'---->打印1...5
    awk 'BEGIN{for(i=1;i<=10;i+=2) print i}'
    awk 'BEGIN{for(i=1;i<=10;i+=2) print i}'|awk '{a+=$1};END{print a}'
    # awk 'BEGIN{for(i=0;i<=50;i+=2) print i}'|awk '{sum+=$1};END{print sum}'
    while循环:
    # awk 'BEGIN{i=1;while(i<=5){print i;i++}}'
    # awk 'BEGIN{i=0;while(i<=10){print i;i+=2}}'
    # awk 'BEGIN{i=0;while(i<=10){print i;i+=2}}'|awk '{sum+=$1}END{print sum}'
    break:条件满足时中断循环
    continue:条件满足时跳过循环
    # awk 'BEGIN{i=0;while(i<=4){i++;if(i==3) continue;print i}}'
    1
    2
    4
    5
    # awk 'BEGIN{i=0;while(i<=4){i++;if(i==3) break;print i}}'
    1
    2
    脚本模式:
    1、命令列表
    2、引用shell变量需要用双引号
    3、#注释
    作业1:
    写一个自动检测磁盘使用率的脚本,当磁盘使用率达到90%以上时,发邮件给管理员root
    作业2:
    写一个自动监控系统内存和交换分区使用情况的脚本;当交换分区的剩余空间小于总空间的30%时,提示留意交换分区,否则显示在正常范围
    判断IP地址是否合法:
    测试如下输入值:
    192.168.0.199
    95.0.0.1
    24.234.2345.1
    192.a1.123.0
    1a2.1.1.0
    01.1.1.1
    123
    ------------------------------------------------------------------------------------------------------------
    #!/bin/bash
    read -p "请输入IP地址:" IP
    #判断所输入的ip地址格式(数字并且是以点分割的4段)
    if [[ "$IP" =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]];then
    ip1=`echo $IP| cut -d. -f1`
    ip2=`echo $IP| cut -d. -f2`
    ip3=`echo $IP| cut -d. -f3`
    ip4=`echo $IP| cut -d. -f4`
    else
    echo "IP wrong!!!" && exit
    fi
    #判断所输入的ip第1、4段都不能以0开头;第2、3段可以是0
    if [[ "$ip1" =~ ^0 ]] || [[ "$ip4" =~ ^0 ]];then
    echo "IP is wrong!" && exit
    elif [[ "$ip2" =~ ^0. ]] || [[ "$ip3" =~ ^0. ]];then
    echo "IP is wrong!!" && exit
    fi
    #判断所输入的ip的范围0~255之间
    for i in $ip1 $ip2 $ip3 $ip4
    do
    if [ $i -lt 0 -o $i -ge 255 ];then
    echo "ip is not ok" && exit
    else
    continue
    fi
    done
    #以上条件都不满足则是符合规范的ip
    echo "IP is ok!"
    -------------------------------------------------------------------------------------------------------------------
    如下代码实现如不输入以点分割的4位数,则一直提示输入正确的ip地址,直到输入以点分割的4位后,再判断其他的
    #!/bin/bash
    fun1(){
    ip=""
    output_var=$1
    while [ -z $ip ] || [[ ! $ip =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]
    do
    read -p "$output_var" ip
    done
    echo $ip
    }
    fun2(){
    IP=`fun1 "Input your ipaddr:[192.168.0.1]"`
    ip1=`echo $IP| cut -d. -f1`
    ip2=`echo $IP| cut -d. -f2`
    ip3=`echo $IP| cut -d. -f3`
    ip4=`echo $IP| cut -d. -f4`
    }
    fun2
    #判断所输入的ip第1、4段都不能以0开头;第2、3段可以是0
    if [[ "$ip1" =~ ^0 ]] || [[ "$ip4" =~ ^0 ]];then
    echo "IP is wrong!" && exit
    elif [[ "$ip2" =~ ^0. ]] || [[ "$ip3" =~ ^0. ]];then
    echo "IP is wrong!!" && exit
    fi
    #判断所输入的ip的范围0~255之间
    for i in $ip1 $ip2 $ip3 $ip4
    do
    if [ $i -lt 0 -o $i -ge 255 ];then
    echo "ip is not ok" && exit
    else
    continue
    fi
    #以上条件都不满足则是符合规范的ip
    done
    echo "IP is ok!"
    ######################################################
    expect 自动应答 TCL(Tool Command Language)语言
    # yum install expect -y
    # rpm -qi expect
    任何有交互性的操作,都可以用expect来做
    1. expect 是基于tcl 演变而来的,所以很多语法和tcl 类似,基本的语法如下
    #!/usr/bin/expect 首行加上/usr/bin/expect
    spawn shell command spawn: 后面加上需要执行的shell 命令,打开一个进程
    expect "xxx" expect: 只有spawn 执行的命令结果才会被expect 捕捉到,因为spawn 会启动一个进程,只有这个进程的相关信息才会被捕捉到
    send "xxxx" send 会将expect 脚本中需要的信息发送给spawn 启动的那个进程
    expect "xxx"
    send "xxx"
    expect eof 代表结束
    执行:
    # ./xxx.sh
    demo1:使用expect修改用户密码
    #!/bin/bash
    expect <<EOF &> /dev/null
    spawn passwd $1 产生passwd $1这个命令
    expect "password:" 当停在password:结尾这个标识符时
    send "123 " 就把123传给它
    send "123 " 当再次停在password:结尾这个标识符时
    send "123 " 就再次把123传给它
    expect eof 表示expect结束
    EOF
    # bash 1.expect test 执行方法,因为脚本里写的是$1,所以后面接你要修改密码的用户名
    demo2:使用expect下载同步ftp共享的文件
    #!/bin/bash
    expect <<EOF &> /dev/null
    spawn lftp 10.1.1.254
    expect ":~>"
    send "get pub/hosts "
    send "quit "
    expect eof
    EOF
    demo3:使用expect实现ssh传密码
    #!/bin/bash
    sed -i '/^'$1'/d' /root/.ssh/known_hosts
    expect << EOF > /dev/null 2>&1
    spawn ssh $1
    expect "no)?"
    send "yes "
    expect "password:"
    send "123456 "
    expect "#"
    send "touch /root/Desktop/123 "
    send "exit "
    expect eof
    EOF
    说明:关于上面跳过yes的问题,可以加下面的参数来做
    ssh 10.1.1.2 -o StrictHostKeyChecking=no
    课堂练习:
    对多台机器的远程expect操作,假设管理的机器有N台,密码也各不相同(没有ssh等效性),现在需要在所有机器上都创建一个文件为/tmp/zhangsan的文件
    # cat ip_user_passwd.list 这个文件里包含你所有管理机器的IP,用户及其对应的密码
    10.1.1.11 root 123
    10.1.1.22 root 111
    10.1.1.33 root 123456
    10.1.1.44 root 54321
    ......
  • 相关阅读:
    LeetCode 485. Max Consecutive Ones
    LeetCode 367. Valid Perfect Square
    LeetCode 375. Guess Number Higher or Lower II
    LeetCode 374. Guess Number Higher or Lower
    LeetCode Word Pattern II
    LeetCode Arranging Coins
    LeetCode 422. Valid Word Square
    Session 共享
    java NIO
    非阻塞IO
  • 原文地址:https://www.cnblogs.com/skyzy/p/9194227.html
Copyright © 2011-2022 走看看