一、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. <NET CLR via c# 第4版>笔记 第8章 方法

    8.1 实例构造器和类(引用类型) 构造引用类型的对象时,在调用类型的实例构造器之前,为对象分配的内存总是先被归零 .没有被构造器显式重写的所有字段都保证获得 0 或 null 值. 构造器不能被继承 ...

  2. L192 Virgin Galactic Completes Test of Spaceship to Carry Tourists

    Virgin Galactic says its spacecraft designed to launch tourists into space completed an important te ...

  3. vue.js 源代码学习笔记 ----- html-parse.js

    /** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...

  4. ubuntu:NVIDIA设置性能模式,以降低CPU使用、温度

    NVIDIA设置性能模式,以降低CPU使用.温度 ubuntu安装完NVIDIA显卡驱动后 终端输入 nvidia-settings 选择OpenGL Settings->Image Setti ...

  5. Buildroot MariaDB替代MySQL

    /********************************************************************************* * Buildroot Maria ...

  6. 基于zookeeper简单实现分布式锁

    https://blog.csdn.net/desilting/article/details/41280869 这里利用zookeeper的EPHEMERAL_SEQUENTIAL类型节点及watc ...

  7. Libusb学习

    1.参考:http://www.cnblogs.com/Daniel-G/archive/2013/04/22/3036730.html https://baike.so.com/doc/506541 ...

  8. O​r​a​c​l​e​ ​D​a​t​a​b​a​s​e​ ​e​x​p​r​e​s​s​ ​1​1​g​ ​第​ ​2​ ​版​安​装和配置

    官方Oracle Database 快捷版 11g 第 2 版的下载地址: http://www.oracle.com/technetwork/cn/products/express-edition/ ...

  9. Linux菜鸟入门级命令大全

    1. man 对你熟悉或不熟悉的命令提供帮助解释eg:man ls 就可以查看ls相关的用法注:按q键或者ctrl+c退出,在linux下可以使用ctrl+c终止当前程序运行.2. ls 查看目录或者 ...

  10. ffmpeg 从内存中读取数据(或将数据输出到内存)(转)

    更新记录(2014.7.24): 1.为了使本文更通俗易懂,更新了部分内容,将例子改为从内存中打开. 2.增加了将数据输出到内存的方法. 从内存中读取数据 ffmpeg一般情况下支持打开一个本地文件, ...