Shell 学习—AWK

= = = 安装awk

root@kiki-desktop:~/shell# apt-get install gawk gawk-doc

= = = awk 是一种程序语言. 它具有一般程序语言常见的功能.

= = =.因awk语言具有某些特点,

如 : 使用直译器(Interpreter)不需先行编译;

变量无类型之分(Typeless), 可使用文字当数组的下标(Associative Array)...等特色. 因此, 使用awk撰写程序比起使用其它语言更简洁便利且节省时间.

awk还具有一些内建功能, 使得awk擅于处理具数据行(Record), 字段(Field)型态的资料;

此外, awk内建有pipe的功能, 可将处理中的数据传送给外部的 Shell命令加以处理, 再将Shell命令处理后的数据传回awk程序, 这个特点也使得awk程序很容易使用系统资源.

= = =  awk程序的主要结构:

awk程序中主要语法是 Pattern { Actions}, 故常见之awk 程序其型态如下 :

Pattern1 { Actions1 }

= = =  Actions 是什么?

Actions 是由许多awk指令构成. 而awk的指令与 C 语言中的指令十分类似.

例如 :

awk的 I/O指令 : print, printf( ), getline...

awk的 流程控制指令 : if(...){..} else{..}, while(...){...}...

= = =  例子

有时语法 Pattern { Actions }中, Pattern 部分被省略,只剩 {Actions}.这种情形表示 "无条件执行这个 Actions".

50 > 23 {print "Hello! The word!!" }

"banana" ~ /123/ { print "Good morning !" }

# awk '{print $2,$3*$4}' emp

UNIX命令行上, 执行awk的语法为:

$awk 'awk程序' 欲处理的资料文件文件名

# cat file1 | awk -F , {'print $1,$2'}

= = =  例如 : awk 从资料文件 emp.dat 中读入第一笔数据行

"A125 Jenny 100 210" 之后, 程序中:

$0 之值将是 "A125 Jenny 100 210"

$1 之值为 "A125"

$2 之值为 "Jenny"

$3 之值为 100

$4 之值为 210

$NF 之值为 4

$NR 之值为 1

$FILENAME 之值为 "emp.dat"

= = =  awk的工作流程 :

执行awk时, 它会反复进行下列四步骤.

自动从指定的数据文件中读取一个数据行.

自动更新(Update)相关的内建变量之值. 如 : NF, NR, $0...

依次执行程序中 所有 的 Pattern { Actions } 指令.

当执行完程序中所有 Pattern { Actions } 时, 若数据文件中还有未读取的数据, 则反复执行步骤1到步骤4.

awk会自动重复进行上述4个步骤, 使用者不须于程序中编写这个循环 (Loop).

= = =  linux中 文本以空格分隔的行就可以默认操作

以其他分隔如, ;等等,就可以用awk –f 操作

dengfang,0Rgbo2Kyn0hms

huyibao,0R1d4zCYO3qxk

dengfeng,0RUsQ9pz6kBPs

gongfangping,0Ru/KhW.8Ove6

liucaigeng,0Rekdi5B0sWfU

= = =  print 的参数间彼此以 "," (逗号) 隔开, 印出数据时彼此间会以空白隔开.

例一,选择符合指定条件的记录

组装部门员工调薪5%,(组装部门员工之ID以"A"开头)

所有员工最后之薪资率若仍低于100, 则以100计.

编写awk程序打印新的员工薪资率报表.

原文件:

A125 Jenny 100 210

A341 Dan 110 215

P158 Max 130 209

P148 John 125 220

A123 Linda 95 210

[root@kiki-desktop:~/shell# cat adjust1.awk

$1 ~ /^A.*/ {$3*=1.05} $3<100 {$3=100}

{printf("%s %8s %d\n",$1,$2,$3)}

root@kiki-desktop:~/shell# cat emp

A125 Jenny 100 210

A341 Dan 110 215

P158 Max 130 209

P148 John 125 220

A123 Linda 95 210

root@kiki-desktop:~/shell# awk -f  adjust1.awk  emp

A125    Jenny 105

100

A341      Dan 115

100

P158      Max 130

100

P148     John 125

100

A123    Linda 100

例二,统计各科修课人数,并印出结果

此为一学生注册的资料文件; 第一栏为学生姓名, 其后为该生所修课程.

Mary O.S. Arch. Discrete

Steve D.S. Algorithm Arch.

Wang Discrete Graphics O.S.

Lisa Graphics A.I.

Lily Discrete Algorithm

.

建立如下程序,并取名为 course.awk:

{ for( i=2; i <= NF; i++) Number[$i]++ }

END{for(course in Number) printf("%10s %d\n", course, Number[course] )}

执行下列命令 :

$awk -f course.awk reg.dat

执行结果如下 :

Graphics 2

O.S. 2

Discrete 3

A.I. 1

D.S. 1

Arch. 2

Algorithm 2

解说:指令中END 为awk之保留字, 为 Pattern 的一种.

END 成立(其值为true)的条件是: "awk处理完所有数据, 即将离开程序时. "

平常读入数据行时, END并不成立, 故其后的Actions 并不被执行;

唯有当awk读完所有数据时, 该Actions才会被执行 ( 注意, 不管数据行有多少笔, END仅在最后才成立, 故该Actions仅被执行一次.)

BEGIN 与 END 有点类似, 是awk中另一个保留的Pattern.

唯一不同的是: "以 BEGIN 为 Pattern 的 Actions 于程序一开始执行时, 被执行一次."

= = = awk中数组的特性

使用字符串当数组的下标(index).

使用数组前不须宣告数组名及其大小.

例如: 希望用数组来记录 reg.dat 中各门课程的修课人数.

这情况,有二项信息必须储存:

(a) 课程名称, 如: "O.S.","Arch.".. ,共有哪些课程事先并不明确.

(b)各课程的修课人数. 如: 有几个人修"O.S."

在awk中只要用一个数组就可同时记录上列信息. 其方法如下:

使用一个数组 Number[ ] :

以课程名称当 Number[ ] 的下标.

以 Number[ ] 中不同下标所对映的元素代表修课人数.

例如:

有2个学生修 "O.S.", 则以 Number["O.S."] = 2 表之.

若修"O.S."的人数增加一人,则 Number["O.S."] = Number["O.S."] + 1 或 Number["O.S."]++ .

例三,写一个awk程序来打印出线上人数.

将下列程序建文件, 命名为 count.awk

BEGIN {

while ( "who" | getline ) n++

print n

}

并执行下列命令 :

awk -f count.awk

执行结果将会印出目前在线人数

getline var

pipe 变量

变量 var(var省略时,表示置于$0)

例四,重定向输出到文件

root@kiki-desktop:~/shell# cat arr.dat

1034 7:26

1025 7:27

1101 7:32

1006 7:45

1012 7:46

1028 7:49

1051 7:51

1029 7:57

1042 7:59

1008 8:01

1052 8:05

1005 8:12

root@kiki-desktop:~/shell# cat reformat1.awk

BEGIN { print " ID Number Arrival Time" > "today_rpt1"

print "===========================" > "today_rpt1"

}

{ printf(" %s %s\n", $1,$2 ) > "today_rpt1" }

root@kiki-desktop:~/shell#

root@kiki-desktop:~/shell#

root@kiki-desktop:~/shell# awk -f reformat1.awk arr.dat

root@kiki-desktop:~/shell#

= = = awk 中如何利用系统资源

注 : awk input 指令只有 getline 一个.

awk output 指令有 print, printf() 二个.

在a 语法中, awk所输出的数据将转送往 Shell , 由 Shell 的命令进行处理.以上例而言, print 所输出的数据将经由 Shell 命令 "sort -k 1" 排序后再送往屏幕(stdout).

上列awk程序中, "print$1, $2" 可能反复执行很多次, 其输出的结果将先暂存于 pipe 中,等到该程序结束时, 才会一并进行 "sort -k 1".

须注意二点 : 不论 print $1, $2 被执行几次, "sort -k 1" 的执行时间是 "awk程序结束时",

[a. 语法] awk output 指令 | "Shell 接受的命令"

( 如 : print $1,$2 | "sort -k 1" )

例5,

root@kiki-desktop:~/shell# awk '

>

> BEGIN{

>

> system("date > date.dat")

>

> getline < "date.dat"

>

> print "Today is ", $2, $3

>

> }

>

> '

Today is  Jan 26

= = = = 执行 awk 程序的几种方式= = = =

若欲执行该awk程序, 来印出文件 today_rpt1 及 today_rpt2 的内容时,

必须于 UNIX 的命令行上执行下列命令 :

方式一 awk -f mydump.awk today_rpt1 today_rpt2

方式二 awk '{print}' today_rpt1 today_rpt2第二种方式系将awk 程序直接写在 Shell 的命令行上, 这种方式仅适合较短的awk程序.

方式三 建立如下之 shell script, 并取名为 mydisplay, $ ./mydisplay today_rpt1 today_rpt2

#!/bin/sh

# 注意以下的 awk 与 ' 之间须有空白隔开

awk '

{print}

' $*

# 注意以上的 ' 与 $* 之间须有空白隔开

例5,$ ./mydisplay  #(未接任何数据文件文件名)

将会发现: 此后键入的任何数据将逐行复印一份于屏幕上. 这情况不是机器当机 ! 是因为awk程序正处于执行中. 它正按程序指示, 将读取数据并重新dump一次; 只因执行时未指定数据文件文件名, 故awk 便以stdin(键盘上的输入)为数据来源. 读者可利用这个特点, 设计可与awk即时聊天的程序.

root@kiki-desktop:~/shell# ./mydisplay

kiki

kiki

kiki

kiki

mina

mina

例6,改变 awk 切割字段的方式 & 自定义函数

范例 : ] 承接 6.2 的例子, 若八点为上班时间, 请加注 "*"于迟到记录之前, 并计算平均上班时间.

Shell 学习—AWK介绍的更多相关文章

  1. shell编程awk基础介绍

    awk介绍 报告生成器,格式化文本输出 处理机制类似sed命令,自带循环处理    读入一行处理一行然后自动读取下一行再进行处理 sed命令换行的标识是固定的,只能是回车换行.    awk里面的换行 ...

  2. shell学习笔记

    shell学习笔记 .查看/etc/shells,看看有几个可用的Shell . 曾经用过的命令存在.bash_history中,但是~/.bash_history记录的是前一次登录前记录的所有指令, ...

  3. AWK增强的文本处理shell特征--AWK完全手册

    AWK这是一个很好的文字处理工具. 它不仅 Linux 中也是不论什么环境中现有的功能最强大的数据处理引擎之中的一个. 本文主要摘录池中龙写的Unixawk使用手冊(第二版),对当中内容略微修改.感谢 ...

  4. shell学习指南-阅读笔记

    shell学习指南真不是刚开始学习shell应该看得书,虽然其中讲了简单的linux命令,shell语法等,但是每章也有些深入和生僻地方,我想如果我刚学shell看到这样的地方一定会头疼的要死.或许也 ...

  5. Shell学习之结合正则表达式与通配符的使用(五)

    Shell学习之结合正则表达式与通配符的使用 目录 通配符 正则表达式与通配符 通配符 通配符的使用 正则表达式 正则表达式 正则表达式的使用 通配符 正则表达式与通配符 正则表达式用来在文件中匹配符 ...

  6. [转帖][Bash Shell] Shell学习笔记

    [Bash Shell] Shell学习笔记 http://www.cnblogs.com/maybe2030/p/5022595.html  阅读目录 编译型语言 解释型语言 5.1 作为可执行程序 ...

  7. shell学习笔记汇总

    1.shell脚本中函数使用 函数定义在前,调用在后,顺序反了就没有效果了.函数调用为:函数名 参数列表 函数内部通过以下变量访问函数的参数:shell脚本函数中: $0: 这个脚本的名字 $n: 这 ...

  8. shell 学习笔记2-shell-test

    一.字符串测试表达式 前面一篇介绍:什么是shell,shell变量请参考: shell 学习笔记1-什么是shell,shell变量 1.字符串测试表达式参数 字符串需要用""引 ...

  9. Shell 学习(二)

    目录 Shell 学习(二) 1 设置环境变量 1.1 基本语法 1.2 实践 2 位置参数变量 2.1 介绍 2.2 基本语法 2.3 位置参数变量应用实例 3 预定义变量 3.1 基本介绍 3.2 ...

随机推荐

  1. Android M AudioPolicy 分析

    1.AudioPolicyService基础 AudioPolicy在Android系统中主要负责Audio"策略"相关的问题.它和AudioFlinger一起组成了Android ...

  2. shell脚本监控MySQL主从同步

    企业面试题1:监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理员. 阶段1:开发一个守护进程脚本每30秒实现检测一次. 阶段2:如果同步出现如下错误号(1158,1159,1008, ...

  3. Hander----使用

    public class MainActivity extends Activity { private EditText UITxt; private Button updateUIBtn; pri ...

  4. [Android Lint] xxx is not translated in xxx 的解决方法

    CLEAN项目即可 转自BLOG http://blog.csdn.net/feng88724/article/details/8835664

  5. assert.fail()

    assert.fail(message) assert.fail(actual, expected[, message[, operator[, stackStartFunction]]]) oper ...

  6. python处理大文件——文件流处理

    最近处理一份1000G+的大文件,直接loading进内存不可能,只能分片读取.文件介绍如下: 该文件是一份压缩的比对后文件(sam文件),该文件由很多细小的结构单元组成,一个结构如下: 两种方法: ...

  7. p4180 次小生成树

    传送门 分析: 次小生成树的求法有两种,最大众的一种是通过倍增LCA找环中最大边求解,而这里我介绍一种神奇的O(nlogn) 做法: 我们先建立最小生成树,因为我们用kruskal求解是边的大小已经按 ...

  8. 5.6 安装slack,Skype,google

    1.将安装包放到自己的目录下: 2.打开终端,进入安装包所在的目录(cd /文件名) 3.输入命令:sudo apt-get install 安装包名 4.等待安装结束 5. 在搜索框中输入关键字sl ...

  9. Umbraco back office 中templates显示不出来问题解决 (一片空白)

    在公司一个项目中,遇到一个问题,登录Umbraco back office,该项目的settings => Templates 已经有该项目的10几个view (templates), 但是,点 ...

  10. [CentOS7] 设备与文件名对应表