简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

使用方法

  1. awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

调用awk

有三种方式调用awk

  1. 1.命令行方式
  2. awk [-F field-separator] 'commands' input-file(s)
  3. 其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
  4. awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
  5.  
  6. 2.shell脚本方式
  7. 将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
  8. 相当于shell脚本首行的:#!/bin/sh
  9. 可以换成:#!/bin/awk
  10.  
  11. 3.将所有的awk命令插入一个单独文件,然后调用:
  12. awk -f awk-script-file input-file(s)
  13. 其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

本章重点介绍命令行方式。

入门实例

假设last -n 5的输出如下

  1. [root@www ~]# last -n 5 <==仅取出前五行
  2. root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in
  3. root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41)
  4. root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48)
  5. dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00)
  6. root tty1 Fri Sep 5 14:09 - 14:10 (00:01)

如果只是显示最近登录的5个帐号

  1. #last -n 5 | awk '{print $1}'
    root
    root
    root
    dmtsai
    root

awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",所以$1表示登录用户,$3表示登录用户ip,以此类推。

如果只是显示/etc/passwd的账户

  1. #cat /etc/passwd |awk -F ':' '{print $1}'
  2. root
  3. daemon
  4. bin
  5. sys

这种是awk+action的示例,每行都会执行action{print $1}。

-F指定域分隔符为':'。

如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割

  1. #cat /etc/passwd |awk -F ':' '{print $1"\t"$7}'
  2. root /bin/bash
  3. daemon /bin/sh
  4. bin /bin/sh
  5. sys /bin/sh

如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"。

  1. cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
  2. name,shell
  3. root,/bin/bash
  4. daemon,/bin/sh
  5. bin,/bin/sh
  6. sys,/bin/sh
  7. ....
  8. blue,/bin/nosh

awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。

在Unix awk中两个特别的表达式,BEGIN和END,这两者都可用于pattern中(参考前面的awk语法),提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。

任何在BEGIN之后列出的操作(在{}内)将在Unix awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。

例:累计销售文件xs中的销售金额(假设销售金额在记录的第三字段):

  1. $awk
  2. 'BEGIN { FS=":";print "统计销售金额";total=0}
  3. {print $;total=total+$;}
  4. END {printf "销售金额总计:%.2f",total}' sx

(注:>是shell提供的第二提示符,如要在shell程序Unix awk语句和Unix awk语言中换行,则需在行尾加反斜杠)

在这里,BEGIN预置了内部变量FS(字段分隔符)和自定义变量total,同时在扫描之前显示出输出行头。而END则在扫描完成后打印出总合计。

搜索/etc/passwd有root关键字的所有行

  1. #awk -F: '/root/' /etc/passwd
  2. root:x:0:0:root:/root:/bin/bash

这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。

搜索支持正则,例如找root开头的: awk -F: '/^root/' /etc/passwd

搜索/etc/passwd有root关键字的所有行,并显示对应的shell

  1. # awk -F: '/root/{print $7}' /etc/passwd
  2. /bin/bash

这里指定了action{print $7}

awk内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

  1. ARGC 命令行参数个数
  2. ARGV 命令行参数排列
  3. ENVIRON 支持队列中系统环境变量的使用
  4. FILENAME awk浏览的文件名
  5. FNR 浏览文件的记录数
  6. FS 设置输入域分隔符,等价于命令行 -F选项
  7. NF 浏览记录的域的个数
  8. NR 已读的记录数
  9. OFS 输出域分隔符
  10. ORS 输出记录分隔符
  11. RS 控制记录分隔符

此外,$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。

统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

  1. #awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
  2. filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
  3. filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
  4. filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
  5. filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh

使用printf替代print,可以让代码更加简洁,易读

  1. awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

print和printf

awk中同时提供了print和printf两种打印输出的函数。

其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。

printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

 awk编程

 变量和赋值

除了awk的内置变量,awk还可以自定义变量。

下面统计/etc/passwd的账户人数

  1. awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
  2. root:x:0:0:root:/root:/bin/bash
  3. ......
  4. user count is  40

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。

这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:

  1. awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
  2. [start]user count is 0
  3. root:x:0:0:root:/root:/bin/bash
  4. ...
  5. [end]user count is 40

统计某个文件夹下的文件占用的字节数

  1. ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
    [end]size is  8657198

如果以M为单位显示:

  1. ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
    [end]size is  8.25889 M

注意,统计不包括文件夹的子目录。

条件语句

awk中的条件语句是从C语言中借鉴来的,见如下声明方式:

  1. if (expression) {
  2. statement;
  3. statement;
  4. ... ...
  5. }
  6.  
  7. if (expression) {
  8. statement;
  9. } else {
  10. statement2;
  11. }
  12.  
  13. if (expression) {
  14. statement1;
  15. } else if (expression1) {
  16. statement2;
  17. } else {
  18. statement3;
  19. }

统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):

  1. ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
    [end]size is  8.22339 M

循环语句

awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。

数组

因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。

显示/etc/passwd的账户

  1. awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
  2. 0 root
  3. 1 daemon
  4. 2 bin
  5. 3 sys
  6. 4 sync
  7. 5 games
  8. ......

这里使用for循环遍历数组

原文地址:http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

【转】【Linux】linux awk命令详解的更多相关文章

  1. linux中awk命令详解(最全面秒懂)

    一:linux中awk命令 1.awk命令简介 AWK 是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinber ...

  2. Linux之awk命令详解

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...

  3. linux下awk命令详解

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...

  4. linux 之awk命令详解

    awk是一种程序语言,对文档资料的处理具有很强的功能.awk名称是由它三个最初设计者的姓氏的第一个字母而命名的: Alfred V. Aho.Peter J. We i n b e rg e r.Br ...

  5. Linux的awk命令详解

    awkawk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,默认以空格为分隔符将每行切片,切开的部分再 ...

  6. linux awk命令详解

    linux awk命令详解 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分 ...

  7. linux awk命令详解,使用system来内嵌系统命令, awk合并两列

    linux awk命令详解 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分 ...

  8. Linux下ps命令详解 Linux下ps命令的详细使用方法

    http://www.jb51.net/LINUXjishu/56578.html Linux下的ps命令比较常用 Linux下ps命令详解Linux上进程有5种状态:1. 运行(正在运行或在运行队列 ...

  9. linux之find命令详解

    linux之find命令详解 查找文件find ./ -type f查找目录find ./ -type d查找名字为test的文件或目录find ./ -name test查找名字符合正则表达式的文件 ...

  10. Linux下rar命令详解

    Linux下rar命令详解 用法: rar <命令> -<选项1> ….-<选项N> < 操作文档> <文件…> <@文件列表…> ...

随机推荐

  1. 哇塞!HTML5 实现的雨滴效果 CSS发抖

    http://dreamsky.github.io/main/blog/rainy-day/ Rainy Day – 哇塞! HTML5 实现的雨滴效果 http://www.webhek.com/m ...

  2. [转]Microsoft Office 2010、Visio 2010、Project 2010官方中文版+有效激活方法

    本文刊发的Office 2010.Project 2010O.Visio 2010:(1)均为“微软批量授权中心”原版光盘镜像:(2)均提供了32位(x86)和64位(x64)两种版本.为使大家了解各 ...

  3. jquery资源

    一.时间日期: 倒计时jQuery插件 Countdown :http://code.google.com/p/jquery-countdown/ 使用案例:http://www.tieyou.com ...

  4. Linux实战教学笔记22:企业级NFS网络文件共享服务

    目录 第二十二节 企业级NFS网络文件共享服务 第一章 NFS网络文件共享服务 1.1 NFS介绍 1.2 NFS系统原理介绍 1.3 NFS服务端部署环境准备 1.4 NFS server端的设置 ...

  5. TransitionsTest

    CCTransitionScene* createTransition(int nIndex, float t, CCScene* s) { // fix bug #486, without setD ...

  6. angular学习笔记(三)-视图绑定数据的两种方式

    绑定数据有两种方式: <!DOCTYPE html> <html ng-app> <head> <title>2.2显示文本</title> ...

  7. Linux GCC编译库

    本文主要解决以下几个问题 1).为什么要使用库? 2).库的分类 3).创建自己的库 为什么要使用库? 或许大家对自己初学 Linux时的情形仍记忆尤新吧.如果没有一个能较好的解决依赖关系的包管理器, ...

  8. C++ Dll 编写入门

    一.前言 自从微软推出16位的Windows操作系统起,此后每种版本的Windows操作系统都非常依赖于动态链接库(DLL)中的函数和数据,实际上 Windows操作系统中几乎所有的内容都由DLL以一 ...

  9. [转帖]cocos2D-X源码分析之从cocos2D-X学习OpenGL(2)----QUAD_COMMAND

    原文:cocos2D-X源码分析之从cocos2D-X学习OpenGL(2)----QUAD_COMMAND 上一篇文章介绍了cocos2d-x的基本渲染结构,这篇顺着之前的渲染结构介绍渲染命令QUA ...

  10. CSS content换行技术实现字符animation loading效果

    一.之前我的字符loading实现 关于字符打点动画实现,我之前使用过box-shadow模拟,还有border+background模拟,还有使用text-shadow实现,以及今年自认为是最好的实 ...