awk 学习小结

来源:互联网 发布:营销qq群发软件 编辑:程序博客网 时间:2024/05/29 19:48

题外话:只是方便自己记忆,以及回顾。

基本上所有的示例和内容都来自书籍:
The AWK Programming Language (Aho, Kernighan, Weinberger 著, 中文名: AWK
程序设计语言)
大神翻译的,不然要我去看英文版。得花更多时间。
https://github.com/wuzhouhui/awk

1.1开始

[root@VM_131_54_centos awklearn]# cat emp.data Beth 4.00 0Dan  3.75 0Kathy 4.00 10Mark 5.00 20Mary 5.50 22Susie 4.25 18

awk执行语句:

[root@VM_131_54_centos awklearn]# awk '$3 > 0 {print $1,$2*$3}' emp.data Kathy 40Mark 100Mary 121Susie 76.5

书中摘抄:

该行命令告诉操作系统运行 awk 程序, 被运行的程序用单引号包围起来, 从输入文件 emp.data 获取 数据. 被单引号包围的部分是一个完整的 awk 程序. 它由一个单独的 [模式–动作] 语句 (pattern-actionstatement) 组成.


1.2) 程序执行过程

书中摘抄:

在上面的命令行中, 被单引号包围的部分是使用 awk语言编写的程序. 每一个 awk 程序都是由一个或多个 模式–动作 语句组成的序列:pattern { action }pattern { action }...awk 的基本操作是在由输入行组成的序列中, 陆续地扫描每一行, 搜索可以被模式 匹配 (match) 的行.“匹配” 的精确含义依赖于问题中的模式, 比如, 对于 $3 > 0, 意味着 “条件为真”每一个输入行轮流被每一个模式测试. 每匹配一个模式, 对应的动作 (可能包含多个步骤) 就会执行.然后下一行被读取, 匹配重新开始. 这个过程会一起持续到所有的输入被读取完毕为止.模式与动作都是可选的, 所以用花括号将动作包围起来, 以便区分两者

1.3 )运行程序的方式:

运行一个 awk 程序有多种方式. 可以键入下面这种形式的命令awk 'program' input files这个命令对指定的输入文件的每一行, 执行 program. 例如你可以键入awk '$3 == 0 { print $1 }' file1 file2来打印文件 file1 与 file2 的每一行的第一个字段 (条件是该行的第 3 个字段为 0).也可以在命令行上省略输入文件, 只要键入awk 'program'在这种情况下, awk 会将 program 应用到你接下来在终端输入的内容上面, 直到键入一个文件结束标志(Unix 系统是组合键 control-d). 下面是一个在 Unix 上运行的例子 4$ awk '$3 == 0 { print $1 }'Beth 4.00 0BethDan 3.75 0DanKathy 3.75 10Kathy 3.75 0Kathy...由 awk 打印的字符加粗显示.这种行为对测试 awk 程序来说非常方便: 键入程序与数据, 检查程序的输出. 我们再次建议读者运行并修改书中的程序.注意到, 命令行中的程序被单引号包围. 这个规定可以防止程序中的字符 (例如 $) 被 shell 解释, 也可以让程序的长度多于一行.当程序的长度比较短时 (只有几行), 这种安排会比较方便. 如果程序比较长, 更好的做法是将它们放在一个单独的文件中, 如果文件名是 progfile 的话, 运行时只要键入awk -f progfile optional list of files选项 -f 告诉 awk 从文件中提取程序. 在 progfile 出现的地方可以是任意的文件名.

2.1) 简单输入(awk的数据类型,以及字段变量)

awk 的数据只有两种类型: 数值与由字符组成的字符串. 文件 emp.data 是很典型的待处理数据,它既含有单词, 也包括数值, 且字段之间通过制表符或空格分隔.awk 从它的输入中每次读取一行, 将行分解为一个个的字段 (默认将字段看作是非空白字符组成的序列). 当前输入行的第一个字段叫作 $1, 第二个是 $2, 依次类推. 一整行记为 $0.每行的字段数有可能不一样.

NF

NF, 字段的数量  ,一行有几个字段,NF做保存[root@VM_131_54_centos awklearn]# awk ' {print NF }' emp.data 333333

NR

NR, 打印行号。[root@VM_131_54_centos awklearn]# awk ' {print NR,$0 }' emp.data 1 Beth 4.00 02 Dan  3.75 03 Kathy 4.00 104 Mark 5.00 205 Mary 5.50 226 Susie 4.25 18

将文本放入输出中

[root@VM_131_54_centos awklearn]# awk ' {print NR,"line",$0 }' emp.data 1 line Beth 4.00 02 line Dan  3.75 03 line Kathy 4.00 104 line Mark 5.00 205 line Mary 5.50 226 line Susie 4.25 18

借助printf产生更美的输出

[root@VM_131_54_centos awklearn]# awk ' {printf ("%s_line:%s\n",NR,$0) }' emp.data 1_line:Beth 4.00 02_line:Dan  3.75 03_line:Kathy 4.00 104_line:Mark 5.00 205_line:Mary 5.50 226_line:Susie 4.25 18

配合其他linux命令进行操作。

比方说sed,sort等等。

sort:  参  数:  -b   忽略每行前面开始出的空格字符。  -c   检查文件是否已经按照顺序排序。  -f   排序时,忽略大小写字母。  -M   将前面3个字母依照月份的缩写进行排序。  -n   依照数值的大小排序。(常用)  -o<输出文件>   将排序后的结果存入指定的文件。  -r   以相反的顺序来排序。  -t<分隔字符>   指定排序时所用的栏位分隔字符。  -k  选择以哪个区间进行排序。[root@VM_131_54_centos awklearn]# awk ' {printf ("%s_line:%s\n",NR,$0) }' emp.data  | sort -n -k 3 -t" "1_line:Beth 4.00 02_line:Dan  3.75 03_line:Kathy 4.00 106_line:Susie 4.25 18   #change4_line:Mark 5.00 205_line:Mary 5.50 22#可以看到第6行跳上去了。


2.2 )选择

1.通过比较来选择:    $2 >= 52.通过计算来选择:    $2 * $3 > 50 { printf("$%.2f for %s\n", $2 * $3, $1) }3.通过文本内容来选择:    $1 == "Susie"    用户也可以搜索含有任意字母, 单词或短语的文本, 通过一个叫做正则表达式(regular expressions) 的模式来完成. 这个程序打印所有包含 Susie 的行: 4.模式组合,即多条件约束匹配    $2 >= 4 || $3 >= 20    !($2 < 4 && $3 < 20)


2.3 )特殊模式:BEGIN 与 END

[root@VM_131_54_centos awklearn]# awk 'BEGIN{print "LINE    NAME   RATE  HOURS"  } \                {printf ("%s_line:%s\n",NR,$0) }' emp.data LINE    NAME   RATE  HOURS1_line:Beth 4.00 02_line:Dan  3.75 03_line:Kathy 4.00 104_line:Mark 5.00 205_line:Mary 5.50 226_line:Susie 4.25 18
原创粉丝点击