一、awk介绍
awk(名字来源于三个创始人姓氏首字母)是linux系统下文本编辑工具,是一门编程语言,有自己的基本语法和流程控制、函数。awk简单高效。
 
二、awk的运行方法
例子:使用冒号:分割/etc/passwd,打印出第一列
1.通过命令行执行
awk -F: '{print $1}' /etc/passwd
 
2.通过执行awk文件来执行
awk文件的格式:
#!/usr/bin/awk
BEGIN{ FS=":"}
{print $1}
 
然后调用这个awk文件的格式:awk -f awk脚本文件 /etc/passwd
 
三、awk的基本语法
awk通过FS作为每一段文本的分割符(默认空格),在命令行上可以用-F参数指定分隔符;
通过RS参数指定文本换行符(默认回车,所以是一行行取数据的),通过换行符作为分割来读取文件。这里区别于sed,sed是一行一行读取文件的
基本流程:
     BEGIN{在读取文件之前做的操作}
     {读取文件时做的操作}
     END{全部文件读取之后才进行的操作}
 
常用内置变量:
     $0  当前所有字段
     $1--$n 按照分隔符分割取到的第n列内容
     FS  分隔符(默认空格) awk 'BEGIN{FS=":"}{print $1}' /etc/passwd ;等价于awk -F: '{print $1}' /etc/passwd
     RS  换行符(默认回车) awk 'BEGIN{RS=":"}{print $1}' /etc/passwd
     NF  字符列数,当前处理行的分割后的列数 awk -F: '{print NF}' /etc/passwd
     NR  行号 awk -F: '{print NR ":" $1}' /etc/passwd
     OFS (默认空格)输出字段分隔符
     ORS (默认回车)输出记录分隔符
 
自定义外部变量:
     -v:自定义变量
     awk -v host=$HOSTNAME "BEGIN{print host}"
 
关系操作符:<、>、<=、>=、==、!=、~、!~
     比较符<等与其他的语言类似,重点说一下不一样的
     ~:用来判断前面的列是否匹配后面的内容。例如awk -F: '$7 ~ /^\/bin/{print $0}' /etc/passwd(判断第7列是否以/bin开头,如果是打印该列)
     !~:不匹配
 
输出:print与printf
     print:直接输出 awk -F: '{print $1 ":" $2}' /etc/passwd
     printf:格式化输出(printf是一个函数,需要用到())
          awk -F: '{printf(hello %s:%s\n),$1,$2}'
          注意:printf需要手动增加\n来换行。使用%s来格式化,printf()外加入要替换的变量
 
四、awk的流程控制
条件:
if语句 if(expression){action1}else{action2}
     例如:产生10个数seq 10,通过if语句判断是单数还是双数
     seq 10 |awk '{if($0%2==0){print $0"是双数"}else{print $0"是单数"}}'
 
如果只需要一个if分支,可以省略前面的if,比如awk -F: '$3<-10 {print $1}' /etc/passwd
 
循环:
while语句:while(expression){action}
     例子:使用:分割/etc/passwd,并将每一列前加上列号
     awk -F: '{i=1;while(i<=NF){print i":"$i;i++ }}' /etc/passwd
 
for语句:
第一种方法:for(i=0;i<=10;i++){action}
     例子:使用:分割/etc/passwd,并将每一列前加上列号
     awk -F: '{for(i=1;i<=NF;i++){print i":"$i}}' /etc/passwd
 
第二种方法:for(value in array){action}
当value在array的key中,进行下面的操作。awk的数组类似python中的字典。
     例子:统计/etc/passwd第7列的值及对应的个数
     awk -F: '{a[$7]++}END{for(i in a)if(i!=""){print i":"a[i]}}' /etc/passwd
     说明:a[$7]:将$7作为数组a的key,然后统计对应的个数;然后遍历for(i in a),判断i是否在数组a的key中;如果存在则打印a[i],a[i]为对应key的值,这里指个数。
 
数组:
array[1]="hello"
array["name"]="Jack"
数组类似python的字典,array[key值]="value值";key为索引,可以是数字也可以是字符串。
数组元素的删除:delete array["key"]
 
     例子:定义了数组a的三个值,并打印结果查看
     awk 'BEGIN{a[1]="hello";a[2]="word";a["name"]="meitian";for(i in a){print "key为"i":value为"a[i]}}'
  
五、awk函数
内置函数
1.算术函数:
int(x) 返回x的整数部分的值,值不会四舍五入,只是取整
sqrt(x) 返回x的平方根
rand() 返回伪随机数r,其中0<=r<1,(伪随机数指返回的值都是上一次返回的同一个随机数)
srand(x) 建立rand()新的种子数,如果没有指定就用当天的时间(使用srand()可以使得rand()返回不同的随机数)
     例子:rand()产生一个随机数,通过srand()产生新的种子数,然后再差生一个随机数
     awk 'BEGIN{print rand();srand();print rand()}'
2.字符串函数:
sub("要替换的字符串","替换后的字符串值"):替换匹配到的第一个文本
     echo "hello world world" | awk '{sub("world","meitian");print $0}'
gsub("要替换的字符串","替换后的字符串值" ):开启全局替换,替换文本中所有匹配到的字符串
     echo "hello world world" | awk '{gsub("world","meitian");print $0}'
     
index("a","b"):返回字符串b在字符串a中开始的位置
     awk 'BEGIN{print index("hello world","world")}'
length("s"):返回字符串s的长度,当没有指定s时,返回$0的长度
      awk -F 'BEGIN{print length("hello world")}{print lenght()}' /etc/passwd
match("s","r"):如果正则表达式r在s中匹配到,则返回出现的起始位置,否则返回0
     awk 'BEGIN{print match("hello world","[wo]")}'
split(s,a,sep) 使用sep将字符串s分解到数组a中,默认sep为FS。
     例子:使用o做为分隔符,将"hello world"进行分割存储到数组a中
     awk 'BEGIN{print split("hello world",a,"o");for(i in a){print a[i]}}'
  
toupper(s):将所有小写字母转换成大写字母
     echo "hello world" |awk '{print toupper($0)}'
tolower(s):将所有大写字母转换成小写字母
     echo "HELLO WORLD" |awk '{print tolower($0)}'
 
自定义函数:
function 函数名(参数1,参数2,...){语句;return 表达式}
     例子:求和
     awk 'function sum(a,b){total=a+b;return total}BEGIN{print sum(2,3)}'
注意:函数必须写在BEGIN{}{}END{}的花括号之外的地方,不能放在任何{}内,否则会报错`return' used outside function context
 
六、实战
1.获得eth0的IP地址
ifconfig eth0 | awk -F":| +" '/inet addr:/{print $4}'
ifconfig eth0的结果:
说明:
1.多个字符作为分隔符(比如例子中的冒号和空格),可以使用|来区分;或者直接使用正则来作区分。比如例子中的-F":| +"可以写成-F"[ :]+"
2.如果要过滤多个相同分隔符,可以使用正则的+。表示1个或多个
3.awk中可以使用'/操作匹配到该内容的行/{匹配到前面的行后进行的操作}'来选择某些想要的行。比如例子中需要取匹配到“inet addr:”的行,打印第4列,//中的为正则表达式,如果有/等需要使用\进行转义
 
2.统计tcp网络连接数
netstat -an |awk  '/^tcp/{a[$NF]++}END{for(i in a){printf("%s:%d\n",i,a[i])}}'
说明:与上面的例子大同小异,/^tcp/表示只处理以tcp开头的行。$NF表示最后一列 
 
七、在实战中可能用到的注意点
1.awk需要对文件进行处理。不需要处理文件的可以把打印命令写在BEGIN里(例如:awk -v name=meitian 'BEGIN{print name}')
2.可以对ls等命令结果进行处理
     例子:对包含conf的文件按照.进行分割,并将分割结果用冒号进行连接
     ls |grep conf |awk -F. '{print $1 ":" $2}'
3.awk使用-v定义变量,但是awk中引用变量时直接使用变量名,不需要在变量前加$
4.将awk中的结果赋值给变量传递给shell中用
方法一:可以使用eval()函数来将打印的结果转换成变量。eval会将打印的值当做命令来进行处理,shell中定义变量的格式:变量名=变量值
     例子:有个文件名为search.contract-0.0.5-SNAPSHOT.jar,按照-分割。将-前面的存为name变量,中间的版本号存为version变量。
     eval $(ls |grep search.contract-0.0.5-SNAPSHOT.jar |awk -F"-" '{printf("name=%s;version=%s\n",$1,$2)}')
 
  
 
方法二:如果只想保存一个变量,可以通过变量名=$(操作print变量值)的方法来保存

     例如提取ifconfig eth0本机中的IP地址保存到变量a中
     a=$(ifconfig eth0 |awk -F":| *" '/inet addr/{print $4}')
  
5.只对包含某些内容的行进行操作
     awk '/要匹配的内容/{进行的操作}' file,//内可以放入正则表达式,注意对一些特殊字符进行转义,比如“[]\“
6.awk不能直接修改源文件,可以通过重导向输出结果来修改原文件。>(全部覆盖文件内容)或>>(追加到文件)
     awk '/^root/{print $0 >"passwd"}' passwd
     注意:重导向输出的文件名要用双引号括起来,否则会报错 
7.awk使用双引号作为分隔符,可以使用单引号括起来,'"'

awk编程基础的更多相关文章

  1. 【转】Shell编程基础篇-下

    [转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...

  2. 【转】Shell编程基础篇-上

    [转]Shell编程基础篇-上 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应 ...

  3. Linux学习之二十一-shell编程基础

    Shell编程基础 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言.Shell 是指一种应用程序,这个应用程序提供了一个 ...

  4. SHELL脚本编程基础知识

    SHELL脚本编程基础知识 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Linux之父Linus有一句话很经典:"Talk is cheap, show me the ...

  5. shell脚本编程基础介绍

    Linux系统——shell脚本编程基础介绍 1.什么是shell 它是一个命令解释器,在linux/unix操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种操作输出的结果 ...

  6. 第二章 Matlab面向对象编程基础

    DeepLab是一款基于Matlab面向对象编程的深度学习工具箱,所以了解Matlab面向对象编程的特点是必要的.笔者在做Matlab面向对象编程的时候发现无论是互联网上还是书店里卖的各式Matlab ...

  7. [.net 面向对象编程基础] (1) 开篇

    [.net 面向对象编程基础] (1)开篇 使用.net进行面向对象编程也有好长一段时间了,整天都忙于赶项目,完成项目任务之中.最近偶有闲暇,看了项目组中的同学写的代码,感慨颇深.感觉除了定义个类,就 ...

  8. Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式

    前言 啦啦啦~(博主每次开篇都要卖个萌,大家是不是都厌倦了呢~) 本篇博文希望帮助大家掌握 Broadcast 编程基础,实现动态注册 Broadcast 和静态注册 Broadcast 的方式以及学 ...

  9. T-Sql编程基础

    T-sql编程 入门小游戏 T-sql编程基础,包括声明变量,if判断,while循环,以及使用一些基本函数. 记得在学校的时候,写过一个二人对打的文字输出游戏. 上代码 alter proc usp ...

随机推荐

  1. Linux下各文件夹的含义和用途

    Linux根目录”/“下各个系统文件夹的含义和用途 1./boot 该目录默认下存放的是Linux的启动文件和内核. 2./initrd 它的英文含义是boot loader initialized ...

  2. New Concept English Two 10 25

    $课文23 新居 219. I had a letter from my sister yesterday. 昨天我收到了姐姐的一封信, 220. She lives in Nigeria. 她住在尼 ...

  3. Centos 7中的网卡一致性命名规则

    一致性网络设备命名,即Consistent Network Device Naming 一.为什么需要这个 服务器通常有多块网卡,有板载集成的,同时也有插在PCIe插槽的. Linux系统的命名原来是 ...

  4. jquery3.1.1报错Uncaught TypeError: a.indexOf is not a function

    jquery3.1.1报错Uncaught TypeError: a.indexOf is not a function 使用1.9就没有问题,解决办法: 就是把写的代码中: $(window).lo ...

  5. MDI窗体及涉及到的相关问题

    MDI窗体是个什么东东尼?多文档窗体唠,相对的还有个SDI,就是单文档窗体.一般情况下我们会将软件的主窗体设置为MDI窗体.那么在主窗体的菜单部分调出来的其他窗体就是主窗体的子窗体了. (1)在主窗体 ...

  6. 《DSP using MATLAB》Problem 2.9

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  7. [CF1016G]Appropriate Team

    codeforces description 给你一个数组\(\{a_i\}\)以及\(X,Y\),问你有多少对\((i,j)\)满足存在一个\(v\in \mathbb{N}^+\)使得 \(\gc ...

  8. C# zedgraph 怎么设置初始时坐标轴的比例??

    http://bbs.csdn.net/topics/390872329 已解决,,,我问是刷新图用的,,我以为mypane.YAxis.Scale.Min=0; mypane.YAxis.Scale ...

  9. Python DB

    #!/usr/bin/python #_*_ coding:utf-8 _*_ import MySQLdb import time import threading import random fr ...

  10. 教你使用markdown画程序流程图

    2016-01-21 10:33:15 星期四 1. 入门案例 st=>start: Start op=>operation: Your Operation sub=>subrout ...