zoukankan      html  css  js  c++  java
  • AWK 介绍

    一.模式和动作

      awk脚本是由模式和操作组成的:pattern {action}

      pattern与{action}两者是可选的。如果没有模式,则action应用到全部记录,如果没有action,则输出匹配全部记录。默认情况下,每一个输入行都是一条记录,但用户可通过RS变量指定不同的分隔符进行分隔。

    模式可以是以下任意一个:

    1. 正则表达式:使用通配符的扩展集。
    2. 关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符
    3. 串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
    4. 模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
    5. BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
    6. END:让用户在最后一条输入记录被读取之后发生的动作。

    操作 由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份:

    1. 变量或数组赋值
    2. 输出命令
    3. 内置函数
    4. 控制流命令

    二. 记录和域

      记录:awk把每一个以换行符结束的行称为一个记录。

      记录分隔符:默认的输入和输出的分隔符都是回车,保存在内建变量ORS和RS中。

      $0变量:它指的是整条记录。如$ awk '{print $0}' test将输出test文件中的所有记录。

      变量NR:一个计数器,每处理完一条记录,NR的值就增加1。

      如$ awk '{print NR,$0}' test将输出test文件中所有记录,并在记录前显示记录号。

      域:记录中每个单词称做“域”,默认情况下以空格或tab分隔。awk可跟踪域的个数,并在内建变量NF中保存该值。

      如$ awk '{print $1,$3}' test将打印test文件中第一和第三个以空格分开的列(域)。

      域分隔符:内建变量FS保存输入域分隔符的值,默认是空格或tab。我们可以通过-F命令行选项修改FS的值。如$ awk -F: '{print $1,$5}' test将打印以冒号为分隔符的第一,第五列的内容。

      可以同时使用多个域分隔符,这时应该把分隔符写成放到方括号中,如$awk -F'[:/t]' '{print $1,$3}' test,表示以空格、冒号和tab作为分隔符。

      输出域的分隔符默认是一个空格,保存在OFS中。如$ awk -F: '{print $1,$5}' test,$1和$5间的逗号就是OFS的值。

    三 . awk内置变量

    变量 描述
    $n 当前记录的第n个字段,字段间由FS分隔。
    $0 完整的输入记录。
    ARGC 命令行参数的数目。
    ARGIND 命令行中当前文件的位置(从0开始算)。
    ARGV 包含命令行参数的数组。
    CONVFMT 数字转换格式(默认值为%.6g)
    ENVIRON 环境变量关联数组。
    ERRNO 最后一个系统错误的描述。
    FIELDWIDTHS 字段宽度列表(用空格键分隔)。
    FILENAME 当前文件名。
    FNR 同NR,但相对于当前文件。
    FS 字段分隔符(默认是任何空格)。
    IGNORECASE 如果为真,则进行忽略大小写的匹配。
    NF 当前记录中的字段数。
    NR 当前记录数。
    OFMT 数字的输出格式(默认值是%.6g)。
    OFS 输出字段分隔符(默认值是一个空格)。
    ORS 输出记录分隔符(默认值是一个换行符)。
    RLENGTH 由match函数所匹配的字符串的长度。
    RS 记录分隔符(默认是一个换行符)。
    RSTART 由match函数所匹配的字符串的第一个位置。
    SUBSEP 数组下标分隔符(默认值是/034)。

    示例 动态获取文件名:

    1 [root@mysql etc]# echo $PWD |awk -F/ '{print $4}'
    2 etc
    3 [root@mysql etc]# echo $PWD |awk -F/ '{print NF}'  #浏览记录的域个数
    4 4
    5 [root@mysql etc]# echo $PWD |awk -F/ '{print $NF}' #动态获最后一个域(文件命)
    6 etc
    7 [root@mysql etc]# 

    四 . awk操作符

    运算符 描述
    = += -= *= /= %= ^= **= 赋值
    ?: C条件表达式
    || 逻辑或
    && 逻辑与
    ~ ~! 匹配正则表达式和不匹配正则表达式
    < <= > >= != == 关系运算符
    空格 连接
    + - 加,减
    * / & 乘,除与求余
    + - ! 一元加,减和逻辑非
    ^ *** 求幂
    ++ -- 增加或减少,作为前缀或后缀
    $ 字段引用
    in 数组成员

    4.1设置输入域到域变量名

    #将$1的值赋给变量ip,ip再与正则匹配
    -bash-3.2$ awk '{ip=$1;if(ip ~/192.168/) print "IP is" ip  }' access.log
    IP is192.168.2.1
    IP is192.168.2.1
    IP is192.168.2.1
    -bash-3.2$ 

    4.2修改数值域取值

    #将$1值 修改为:192.168.2.11
    -bash-3.2$ awk '{ if( $1=="192.168.2.1") $1="192.168.2.11"; print $1}' access.log
    192.168.2.11
    192.168.2.11
    192.168.2.11
    -bash-3.2$

    4.3 汇总列值

    -bash-3.2$ awk '(tot+=$4) { print $4 };END{ print "total is : " tot}' test.txt
    5013.14
    3155.59
    2142.03
    3000.00
    2000.00
    2000.00
    1000.00
    13083.41
    5000.00
    total is : 36394.2
    -bash-3.2$

    4.4 向一行awk命令传值

    -bash-3.2$ who | awk '{if ($1 == user) print $1 " you are connected to:" $2}' user=$LOGNAME

    4.5 将域($1,$2,$3.....)作为变量传入awk

    -bash-3.2$ awk -F"|" '{print $i}' i=1

    4.6 通过while语句实现循环

    -bash-3.2$ awk '{ i=1;while(i<NF) {print NF,$i;i++}}' test.txt

    4.7通过for语句实现循环

    -bash-3.2$ awk '{ for(i=1;i<NF;i++) {print NF,$i}}' test.txt

    注:在awk中调用系统变量必须用单引号,如果是双引号,则表示字符串

    五 . 内置的字符串函数

    gsub(r,s) 在整个$0中用s替代r,gsub返回值为替换次数     
    gsub(r,s,t) 在整个t中用s替代r                           
    index(s,t) 返回s中字符串t的第一位置                    
    length(s) 返回s长度                                   
    match(s,r) 测试s是否包含匹配r的字符串                  
    split(s,a,fs) 在fs上将s分成序列a                          
    sprint(fmt,exp) 返回经fmt格式化后的exp                      
    sub(r,s) 用$0中最左边最长的子串代替s                 
    substr(s,p) 返回字符串s中从p开始的后缀部分              
    substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分  

    示例:

    5.1.gsub
    awk 'gsub(/^root/,"netseek") {print}' /etc/passwd 将与root开头的root替换为netseek
    
    awk 'gsub(/0/,2) {print}' /etc/fstab
    
    awk '{print gsub(/0/,2) $0}' /etc/fstab
    
    5.2.index
    awk 'BEGIN {print index("root","o")}' 查询字符串root中o出现的第一位置
    
    awk -F: '$1=="root" {print index($1,"o")" "$1}' /etc/passwd
    
    awk -F: '{print index($1,"o") $1}' /etc/passwd
    
    5.3.length
    awk -F: '{print length($1)'} /etc/passwd
    
    awk -F: '$1=="root" {print length($1)}' /etc/passwd
    
    5.4.match (在ANCD中查找C的位置)
    awk 'BEGIN {print match("ANCD",/C/)}'
    
    5.5.split
    返回字符串数组元素个数
    awk 'BEGIN {print split("123#456#789", myarray, "#")}'
    
    5.6.sub 只能替换指定域的第一个0
    awk 'sub(/0/,2) {print }' /etc/fstab
    
    5.7.substr
    按照起始位置及长度返回字符串的一部分
    awk 'BEGIN {print substr("www.linuxtone.org",5,9)}' //第5个字符开始,取9个字符。
    
    awk 'BEGIN {print substr("www.linuxtone.org",5)}' //第5个位置开始,取后面的所有.
  • 相关阅读:
    (转)HTTP协议
    函数深入理解---函数的定义方式
    DOM模型和事件处理---事件处理
    DOM模型和事件处理---节点操作
    DOM模型和事件处理---基本操作
    常用知识
    窗口对象
    简单的事件处理
    Grunt
    基本操作
  • 原文地址:https://www.cnblogs.com/polestar/p/3172086.html
Copyright © 2011-2022 走看看