Linux命令学习手册-awk
awk '条件类型1{动作1} 条件类型2{动作2} ...' filename
功能
相较于 sed
常常作用于一整个行的处理, awk
则比较倾向于一行当中分成数个『字段』来处理。
描述
awk 的处理流程
读入第一行,并将第一行的资料填入 $0, $1, $2…. 等变数当中;
依据 “条件类型” 的限制,判断是否需要进行后面的 “动作”;
做完所有的动作与条件类型;
若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。
经过这样的步骤,您会晓得, awk 是『以行为一次处理的单位』, 而『以字段为最小的处理单位』。
常用变量(变量名称 代表意义)
NF
每一行 ( $0
) 拥有的字段总数
NR
目前 awk 所处理的是『第几行』数据
FS
目前的分隔字符,预设是空格键
每一行的每个字段的变量名称就是 $1
, $2
… 等。还有个例外,那就是 $0
代表一整行的意思。
注意, awk
后续的所有动作以 ‘ 括住, 所以,内容如果想要以 print
打印时,记得,非变量的文字部分, printf
提到的格式中,都需要使用双引号.
逻辑运算符号
大于
< 小于
= 大于或等于
<= 小于或等于
== 等于
!= 不等于
举例
假设输入输出如下:
$lastdmtsai pts/0 192.168.1.12 Mon Aug 22 09:40 still logged inroot tty1 Mon Aug 15 11:38 - 11:39 (00:01)reboot system boot 2.6.11 Sun Aug 14 18:18 (7+15:41)dmtsai pts/0 192.168.1.12 Fri Aug 12 12:07 - 12:08 (00:01)
打印每行的第1列和第三列,并且用[TAB]隔开
输入输出如下
$last | awk '{print $1 "\t" $3}'dmtsai 192.168.1.12root Monreboot bootdmtsai 192.168.1.12
这里,我们没有设定条件,也就是无论哪一行都做同样处理,所以第2,3行显示的有点”不正常”。由此可知awk是“迭代”处理每一行的。
列出每一行的账号,目前处理的行数, 以及该行有多少字段
输入输出如下
$last | awk '{print $1 "\t lines: " NR "\t columes: " NF}'dmtsai lines: 1 columes: 10root lines: 2 columes: 9reboot lines: 3 columes: 9dmtsai lines: 4 columes: 10
查阅
/etc/passwd
,第3栏小于 10 以下的数据,并且仅列出账号与第3栏输入输出如下:
$cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t " $3}'root:x:0:0:root:/root:/bin/bashbin 1daemon 2......(以下省略)......
这里,在
/etc/passwd
当中是以冒号 “:” 来作为字段的分隔,所以需要设置一下。但是我们读入第一行的时候, 那些变数 $1, $2… 预设还以空格键为分隔,所以虽然我们定义了 FS=”:” 了, 但是却仅能在第二行后才开始生效(可能因为一般第一行仅仅是列名不需处理,而这里却是特例,见例4改进)。对上面过滤的操作改进
输入输出如下:
$ cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'root 0bin 1daemon 2......(以下省略)......
利用 BEGIN 这个关键词,可以从第一行就生效了。实际除了BEGIN,还有END。
假设如下表(pay.txt)
Name 1st 2nd 3thVBird 23000 24000 25000DMTsai 21000 20000 23000Bird2 43000 42000 41000
计算每一行总额,添加追加到最后一列
输入输出如下:
$awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total" }NR>=2{total = $2 + $3 + $4printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}'Name 1st 2nd 3th TotalVBird 23000 24000 25000 72000.00DMTsai 21000 20000 23000 64000.00Bird2 43000 42000 41000 126000.00
注意:所有的动作在
{}
内,如需多个指令辅助,可利用分号;
间隔或直接以[Enter]
按键来隔开每个指令,例如上面的 NR>=2 后面接的动作, 利用 total = … 那个指令来指定加总,而后续则以printf
来格式化输;格式化输出时,在printf
的格式设定当中,务必加上\n
,才能进行分行;与bash shell
的变量不同,在awk
当中,变量可以直接使用,不需加上$
符号(如total)。
其它
参考资料: 《鸟哥的私房菜》
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
Linux命令学习手册-awk
下载Word文档到电脑,方便收藏和打印~
相关文章
- Java 中 strip 函数的效率究竟如何?(Java strip函数的效率怎样)
- 在 Java 中如何编写结束程序的代码?(java中结束程序代码怎么写)
- Java 中如何给空数组进行赋值?(java怎么给空数组赋值)
- Java 中 final 的具体功能有哪些?(java中final的功能有哪些)
- 如何加强 Java CronTriggerBean 的安全性?(Java CronTriggerBean安全性怎样加强)
- Java 如何实现调用外部接口?(java怎么调用外部接口)
- Java 中 java.lang.String 类的使用方法有哪些?(java.lang.String类如何使用)
- Java 注解的创新应用有哪些?(Java注解有何创新应用)
- Java Socket 编程在跨平台环境下的表现究竟如何?(java socket编程在跨平台中表现如何)
- 掌握Ruby加密解密:如何进行有效的测试