10章:awk进阶操作

     在第4章:查找与替换简单的讲解了awk的使用,本章介绍详细讲解awk的使用。awk是一个强大的文本分析工具,简单的说awk就是把文件逐行的读入,

  以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。在shell脚本中文本处理功能awk功能其强大。

7.1awk命令形式

awk命令在shell脚本基本形式通常由四部分组成: [-F|-f|-v] (参数选项)、BEGIN语句块(初始化代码块)、pattern{commadns}(能够使用模式匹配的通用语句块)、END语句块(结束代码块),这四部分是可选择的,任意一部分都可以不出现在脚本中,后面三部分通常是被单引号或双引号括起来,awk命令形式如下所示:

awk [-F|-f|-v]  ‘BEGIN{ commands }  /pattern/{ commands }  END{ commands}’  filename

 

四部分分别代表意义:

[-F|-f|-v]    参数选项:-F指定分隔符,-f调用脚本,-v定义变量 如var=value。

BEGIN{ commands }  初始化代码块:在对第一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符。

/pattern/{ commands }  匹配代码块和命令代码块:/pattern/匹配代码块,pattern可以是字符串或正则表达式;{ commands } 命令代码块,commadns可包含一条或多条命令。

END{ commands }   结尾代码块:在对每一行进行处理之后再执行的代码块,主要是进行最终的计算或输出结尾摘要信息。

awk工作原理:

第一步:执行BEGIN{ commands }语句块中的语句,可以选择[-F|-f|-v]参数选项一起执行。

第二步:从文件或标准输入(stdin)读取一行,然后执行/pattern/{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。

第三步:当读至输入流末尾时,执行END{ commands }语句块。

BEGIN语句块在awk开始从输入流中读取行之前被执行,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中,可以选择[-F|-f|-v]参数选项一起使用,这两部分是可选的。

pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供/pattern/语句块,则默认执行{ commands },即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是可选的。

范例:以#号为分格符,分别输出两行,$1代表第一个字段,$2代表第二个字段。

[root@cloucentos6 ~]# echo -e "A line 1#A line 2" | awk -F "#" 'BEGIN{ print "Start" } {print $1 "\n" $2} END{ print "End" }'

Start

A line 1

A line 2

End

7.2awk内置变量

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

举例:

Linux系统创建了一个测试文本list,后续部分范例操作会以文本list为测试文件,测试文本list内容如下:

[root@cloucentos6 home]# cat list

John Daggett, 341 King Road, Plymouth MA

Alice Ford, 22 EAST Broadway, Richmond VA

Orville Thomas, 11345 Oak Bridge Road, Tulsa OK

Terry Kalkas, 402 Lans Road, Beaver Falls PA

Eric Adams, 20 Post Road, Sudbury MA

Hubert Sims, 328A Brook Road, Roanoke VA

Amy Wilde, 334 Bayshore Pkwy, Mountain View CA

Sal Carpenter, 73 6th Street, Boston MA

范例1:$1显示第一列,awk如果没有指定分界符,默认以空格或制表符为分界符。

[root@cloucentos6 home]# awk  '{print $1}'  list

John

Alice

Orville

Terry

Eric

Hubert

Amy

Sal

知识点补充:$2代表第二列,以此类推,如果是$10以上,不能直接使用$10需要加上括号如:$(10)

范例2:$0输出当前文本内容。

[root@cloucentos6 home]# awk  '{print $0}'  list

John Daggett, 341 King Road, Plymouth MA

Alice Ford, 22 EAST Broadway, Richmond VA

Orville Thomas, 11345 Oak Bridge Road, Tulsa OK

Terry Kalkas, 402 Lans Road, Beaver Falls PA

Eric Adams, 20 Post Road, Sudbury MA

Hubert Sims, 328A Brook Road, Roanoke VA

Amy Wilde, 334 Bayshore Pkwy, Mountain View CA

Sal Carpenter, 73 6th Street, Boston MA

范例3使用NR统计文本中的行数,打印指定的行和列。

[root@cloucentos6 home]# awk  '{print NR}'  list

1

2

3

4

5

6

7

8

[root@cloucentos6 home]# awk  'END{print NR}'  list

8

[root@cloucentos6 home]# nl list | awk 'NR==3{print}'

3     Orville Thomas, 11345 Oak Bridge Road, Tulsa OK

[root@cloucentos6 home]# nl list | awk 'NR==3{print $2}'

Orville

范例4:”/ /”模式,主要用于匹配正则表达式

[root@cloucentos6 home]# awk '/MA/' list

John Daggett, 341 King Road, Plymouth MA

Eric Adams, 20 Post Road, Sudbury MA

Sal Carpenter, 73 6th Street, Boston MA

[root@cloucentos6 home]# awk '/MA/ {print $1}' list

John

Eric

Sal

范例5选项 –F 指定字段的分隔符

[root@cloucentos6 home]# awk -F ',' '{print $1 $2}' list

John Daggett 341 King Road

Alice Ford 22 EAST Broadway

Orville Thomas 11345 Oak Bridge Road

Terry Kalkas 402 Lans Road

Eric Adams 20 Post Road

Hubert Sims 328A Brook Road

Amy Wilde 334 Bayshore Pkwy

Sal Carpenter 73 6th Street

[root@cloucentos6 home]# awk -F ',' '{print $1;print $2}' list

John Daggett

341 King Road

Alice Ford

22 EAST Broadway

Orville Thomas

11345 Oak Bridge Road

Terry Kalkas

402 Lans Road

Eric Adams

20 Post Road

Hubert Sims

328A Brook Road

Amy Wilde

334 Bayshore Pkwy

Sal Carpenter

73 6th Street

知识点补充:多重命令使用分号隔开。

范例6选项 –f 直接调用脚本或文本里的内容

[root@cloucentos6 home]# cat filename

/MA/{print "第" NR "行:"  "内容:" $0}

[root@cloucentos6 home]# awk -f filename list

第1行:内容:John Daggett, 341 King Road, Plymouth MA

第5行:内容:Eric Adams, 20 Post Road, Sudbury MA

第8行:内容:Sal Carpenter, 73 6th Street, Boston MA

范例7内置变量NF,NF显示文本每一行的字段数量,$NF显示文本最后一列。

[root@cloucentos6 home]# awk '{print $NF}' list

MA

VA

OK

PA

MA

VA

CA

MA

[root@cloucentos6 home]# awk '{print NF}' list

7

7

8

8

7

7

8

7

范例8借助-v选项,可以将变量的值传递给awk,有两种传递方法。

方法一:

[root@cloucentos6 home]# cat test.sh

#!/bin/bash

var=1000

echo | awk -v vartable=$var '{print vartable}'

[root@cloucentos6 home]# ./test.sh

1000

方法二:

[root@cloucentos6 home]# cat test.sh

#!/bin/bash

var1=1000

var2=2000

echo | awk '{print v1,v2}' v1=$var1 v2=$var2

[root@cloucentos6 home]# ./test.sh

1000 2000

范例9向脚本传递参数

[root@cloucentos6 home]# cat test.sh

#!/bin/bash

#在awk命令中$1代表输入行的第一列字段,而在shell脚本中$1代表命令行提供的第一个参数

#把shell脚本$1第一个参数赋值给var,再将var赋值给awk$1第一列字段

awk '$1=var' var=$1 list

[root@cloucentos6 home]# ./test.sh  ABC

ABC Daggett, 341 King Road, Plymouth MA

ABC Ford, 22 EAST Broadway, Richmond VA

ABC Thomas, 11345 Oak Bridge Road, Tulsa OK

ABC Kalkas, 402 Lans Road, Beaver Falls PA

ABC Adams, 20 Post Road, Sudbury MA

ABC Sims, 328A Brook Road, Roanoke VA

ABC Wilde, 334 Bayshore Pkwy, Mountain View CA

ABC Carpenter, 73 6th Street, Boston MA

范例10:awk命令嵌套if判断语句和for循环语句。

###判断当前文件和目录大于500字节的文件打印出文件和大小

[root@cloucentos6 home]# ls -l | awk '{if (($5>=500)) print "\n" "文件: " $9 "\n" "大小: " $5 "B" "\n"}'

文件: lost+found

大小: 16384B

###判断当前目录文本大于300字节的文件打印出文件和大小

[root@cloucentos6 home]# ls -l | awk '{if (( $5>=300 && /^-/ )) print "\n" "文本: " $9 "\n" "大小: " $5 "B" "\n"}'

文本: list

大小: 341B

文本: list.bak

大小: 341B

#把abcde字符串按顺序逐个输出

[root@cloucentos6 home]# echo "abcde" | awk -F '' '{for(i=1;i<=NF;i++) print $i}'

a

b

c

d

e

[root@cloucentos6 home]# echo "abcde" | awk -F '' '{for(i=NF;i>=1;i--) print $i}'

e

d

c

b

a

范例11:awk命令提供两个函数用于完成字符串大小写转换,函数为小写tolower()和大写toupper()。

[root@cloucentos6 home]# awk '{print tolower($0)}' list

john daggett, 341 king road, plymouth ma

alice ford, 22 east broadway, richmond va

orville thomas, 11345 oak bridge road, tulsa ok

terry kalkas, 402 lans road, beaver falls pa

eric adams, 20 post road, sudbury ma

hubert sims, 328a brook road, roanoke va

amy wilde, 334 bayshore pkwy, mountain view ca

sal carpenter, 73 6th street, boston ma

[root@cloucentos6 home]# awk '{print toupper($0)}' list

JOHN DAGGETT, 341 KING ROAD, PLYMOUTH MA

ALICE FORD, 22 EAST BROADWAY, RICHMOND VA

ORVILLE THOMAS, 11345 OAK BRIDGE ROAD, TULSA OK

TERRY KALKAS, 402 LANS ROAD, BEAVER FALLS PA

ERIC ADAMS, 20 POST ROAD, SUDBURY MA

HUBERT SIMS, 328A BROOK ROAD, ROANOKE VA

AMY WILDE, 334 BAYSHORE PKWY, MOUNTAIN VIEW CA

SAL CARPENTER, 73 6TH STREET, BOSTON MA

范例12:awk命令提供一个统计字符串长度的函数length()。

[root@cloucentos6 home]# echo "abcde" | awk '{print length($0)}'

5

[root@cloucentos6 home]# echo "abcde" | awk -F '' '{print NF}'

5

[root@cloucentos6 home]# echo "abcde" | wc -L

5

[root@cloucentos6 home]# cat test.sh

#!/bin/bash

var="abcde"

echo ${#var}

[root@cloucentos6 home]# ./test.sh

5

第10章:awk进阶操作的更多相关文章

  1. 第10章:MongoDB-CRUD操作--文档--修改--修改器

    ① $set:进行内容的重新设置 语法:{"$set" : {"成员" : "新内容"}}: 范例:将年龄是20岁的人的成绩修改为89 db ...

  2. 第11章:sed进阶操作

    第11章:sed进阶操作 sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法 sed命令行格式为 ...

  3. Linux就这个范儿 第10章 生死与共的兄弟

    Linux就这个范儿 第10章 生死与共的兄弟 就说Linux系统的开机.必须经过加载BIOS.读取MBR.Boot Loader.加载内核.启动init进程并确定运行等级.执行初始化脚本.启动内核模 ...

  4. 第10章 系统级I/O

    第10章 系统级I/O 10.1 Unix I/O 一个Unix文件就是一个m个字节的序列:B0,B1,…,BK,…,Bm-1 Unix I/O:一种将设备优雅地映射为文件的方式,允许Unix内核引出 ...

  5. 高性能Linux服务器 第10章 基于Linux服务器的性能分析与优化

    高性能Linux服务器 第10章    基于Linux服务器的性能分析与优化 作为一名Linux系统管理员,最主要的工作是优化系统配置,使应用在系统上以最优的状态运行.但硬件问题.软件问题.网络环境等 ...

  6. [原创]Scala学习:数组的基本操作,数组进阶操作,多维数组

    1.Scala中提供了一种数据结构-数组,其中存储相同类型的元素的固定大小的连续集合.数组用于存储数据的集合,但它往往是更加有用认为数组作为相同类型的变量的集合 2 声明数组变量: 要使用的程序的数组 ...

  7. JavaScript高级程序设计(第三版)学习笔记8、9、10章

    第8章,BOM BOM的核心对象是window,具有双重角色,既是js访问浏览器的一个接口,又是ECMAScript规定的Global对象.因此,在全局作用域中声明的函数.变量都会变成window对象 ...

  8. Django中的ORM进阶操作

    Django中的ORM进阶操作 Django中是通过ORM来操作数据库的,通过ORM可以很easy的实现与数据库的交互.但是仍然有几种操作是非常绕也特别容易混淆的.于是,针对这一块,来一个分类总结吧. ...

  9. 《Android开发艺术探索》读书笔记 (10) 第10章 Android的消息机制

    第10章 Android的消息机制 10.1 Android消息机制概述 (1)Android的消息机制主要是指Handler的运行机制,其底层需要MessageQueue和Looper的支撑.Mes ...

随机推荐

  1. 整理Lua和Unity和Lua交互文章链接

    重点文章: 1.[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 2.[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(中) 3.Lua和C++交互详细总结 4. ...

  2. sql乘法函数实现方式

    sql中有很多聚合函数,例如 COUNT.SUM.MIN 和 MAX. 但是唯独没有乘法函数,而很多朋友开发中缺需要用到这种函数,今天告诉大家一个不错的解决方案 logx+logy=logx*y 这是 ...

  3. MFC中获取命令行参数的几种方法

    在MFC程序中,可以用以下几种方法来获取命令行参数. 为方便说明,我们假设执行了命令:C:\test\app.exe -1 -2 方法一 ::GetCommandLine(); 将获取到 " ...

  4. 线程安全的无锁RingBuffer的实现【一个读线程,一个写线程】

    在程序设计中,我们有时会遇到这样的情况,一个线程将数据写到一个buffer中,另外一个线程从中读数据.所以这里就有多线程竞争的问题.通常的解决办法是对竞争资源加锁.但是,一般加锁的损耗较高.其实,对于 ...

  5. ios 6.1中 Release问题

    程序中有如下代码: UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Something was done." m ...

  6. [转]你所不知的 CSS ::before 和 ::after 伪元素用法

    SS 有两个说不上常用的伪类 :before 和 :after,偶尔会被人用来添加些自定义格式什么的,但是它们的功用不仅于此.前几天发现了 Creative Link Effects 这个非常有意思的 ...

  7. 解决Eclipse异常关闭后重启报 org.eclipse.swt.SWTException: Invalid thread access 的问题

    . . . . . 很久没有写博客了,最近实在是太忙,一直想写点干货,但是一直没静下心来学习. 今天又在加班忙碌之中,结果谁知道越忙碌越出问题.先是 weblogic 没有正常启动,凭经验第一反应就是 ...

  8. 新浪微博 oauth2.0 redirect_uri_mismatch

    新浪微博开放平台出来很久了,现在才开始研究,貌似有点晚了.... 第一次折腾,总是出现这样那样的问题,即使照着别人成功的例子也是一样,这不,开始运行的时候,运行下面的例子,总是报error:redir ...

  9. Android——继续深造——从安装Android Studio 2.0开始(详)

    一.下载JDK,JRE,SDK http://jingyan.baidu.com/article/eb9f7b6d884ea7869364e8eb.html 二.配置环境变量: 我的电脑->属性 ...

  10. backbone的对象继承实现

    通过原型链实现对象的继承,子类通过’__super__‘来访问父类的方法 // protoProps 子类的属性参数 // staticProps 静态属性 var extend = function ...