awk 学习小结

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

基本上所有的示例和内容都来自书籍:
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 0
Dan  3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18

awk执行语句:

[root@VM_131_54_centos awklearn]# awk '$3 > 0 {print $1,$2*$3}' emp.data 
Kathy 40
Mark 100
Mary 121
Susie 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 0
Beth
Dan 3.75 0
Dan
Kathy 3.75 10
Kathy 3.75 0
Kathy
...
由 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 
3
3
3
3
3
3
NR
NR, 打印行号。
[root@VM_131_54_centos awklearn]# awk ' {print NR,$0 }' emp.data 
1 Beth 4.00 0
2 Dan  3.75 0
3 Kathy 4.00 10
4 Mark 5.00 20
5 Mary 5.50 22
6 Susie 4.25 18
将文本放入输出中
[root@VM_131_54_centos awklearn]# awk ' {print NR,"line",$0 }' emp.data 
1 line Beth 4.00 0
2 line Dan  3.75 0
3 line Kathy 4.00 10
4 line Mark 5.00 20
5 line Mary 5.50 22
6 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 0
2_line:Dan  3.75 0
3_line:Kathy 4.00 10
4_line:Mark 5.00 20
5_line:Mary 5.50 22
6_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 0
2_line:Dan  3.75 0
3_line:Kathy 4.00 10
6_line:Susie 4.25 18   #change
4_line:Mark 5.00 20
5_line:Mary 5.50 22
#可以看到第6行跳上去了。


2.2 )选择

1.通过比较来选择:
    $2 >= 5
2.通过计算来选择:
    $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  HOURS
1_line:Beth 4.00 0
2_line:Dan  3.75 0
3_line:Kathy 4.00 10
4_line:Mark 5.00 20
5_line:Mary 5.50 22
6_line:Susie 4.25 18
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值