linux-shell-04 shell-脚本四剑客-awk
概念解析
AWK是一种处理文本文件的语言,是一个强大的文本分析工具。之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
awk本身就是一种编程语言,它支持条件判断、循环、数组遍历等功能。我们可以使用它来对文本进行分析和处理。与sed相比,sed是逐行处理文本内数据,awk也是,不过awk又在此基础上实现对每一行每一列的操作。专业的角度来讲awk是一个报告生成器,因为awk可以对行和列进行操作,所以在awk命令下,一个文本就像是一个表格。默认列之间的分隔符是空格,行之间分隔符是\n,可以通过-F或者-v FS:指定分割符。
语法
1 | awk [选项参数] 'script' var=value file(s) |
选项参数说明
1 | -F fs or --field-separator fs |
基本用法
用法一
1 | awk '{pattern + action}' {filenames} |
1.基本语法参数
1.单引号‘’:为了和shell语法分开,防止混淆,行匹配语句 awk ‘’ 只能用单引号
2.大括号{}:用来表示一组命令
3.pattern:一个过滤器,表示匹配pattern的条件的行才可以执行action
4.pattern可以是以下任意一种
-正则表达式:使用通配符匹配
-关系表达式:使用关系运算符
-模式匹配表达式:使用运算符~或者!~匹配
5.action:处理动作,一系列命令,常见的动作为print
实例:每行按空格或TAB分割,输出文本中的1、4项
1 | [root@localhost ~]# vim 1.txt |
用法二
1 | awk -F #-F相当于内置变量FS, 指定分割字符 |
实例: 使用”,”作为分割字符
1 | [root@localhost ~]# awk -F, '{print $1,$2}' 1.txt |
用法三
1 | awk -v # 设置变量 |
实例:设置一个叫做xxx的变量,值为100,那么$1+xxx=每行第一个项加100的和,$1xxx表示每行第一个项与xxx衔接的结果。
1 | [root@localhost ~]# cat 1.txt |
用法四
1 | awk -f {awk脚本} {文件名} |
实例:
1 | [root@localhost ~]# vim test.awk |
awk脚本首行都是#! /usr/bin/awk -f,以为awk解释器的路径就是 /usr/bin/awk。
运算符
运算符 | 描述 | ||
---|---|---|---|
= += -= *= /= %= ^= **= | 赋值 | ||
?: | C条件表达式 | ||
\ | \ | 逻辑或 | |
&& | 逻辑与 | ||
~ ~! | 匹配正则表达式和不匹配正则表达式 | ||
< <= > >= != == | 关系运算符 | ||
空格 | 连接 | ||
+ - | 加,减 | ||
* / % | 乘,除与求余 | ||
+ - ! | 一元加,减和逻辑非 | ||
^ *** | 求幂 | ||
++ – | 增加或减少,作为前缀或后缀 | ||
$ | 字段引用 | ||
in | 数组成员 |
运算符实例
过滤出第一列大于2的行
1 | [root@localhost ~]# cat 1.txt |
过滤第一列等于6的行
1 | [root@localhost ~]# awk '$1==6' 1.txt |
过滤第一列大于2并且第二列等于7的行
1 | [root@localhost ~]# awk '$1>2&& $2==7' 1.txt |
使用正则,字符串匹配
输出第二列包含 “python”的那一行的第1列与第2列。
1 | [root@localhost ~]# awk '$2 ~ /python/ {print $1,$2}' 1.txt |
注意:~ 表示模式开始。// 中是模式。
输出包含”java” 的行
1 | [root@localhost ~]# awk '/java/' 1.txt |
给1.txt增加一行大写内容
1 | [root@promote ~]# vim 1.txt |
输出包含java的行,不区分大小写
1 | [root@promote ~]# awk 'BEGIN{IGNORECASE=1} /java/' 1.txt |
输出不包含java的行,不区分大小写
1 | [root@promote ~]# awk 'BEGIN{IGNORECASE=1} !/JavA/' 1.txt |
awk脚本
helloworld
1 | [root@promote ~]# vim a.awk |
关于awk脚本,我们需要注意两个关键词BEGIN和END。
- BEGIN{ 这里面放的是执行前的语句 }
- END {这里面放的是处理完所有的行后要执行的语句 }
- 中间{这里面放的是处理每一行时要执行的语句}
1 | [root@node4 ~]# cat a.awk |
执行结果如下:
敲回车后进入到中间部分的代码
可是现在无论如何敲回车,也没有办法退出该部分代码,进入不到end部分。原因是执行脚本的时候没有参数。
先建一个2.txt作为测试对象
1 | [root@node4 ~]# cat 2.txt |
修改脚本,然后执行
1 | [root@node4 ~]# vim a.awk |
awk用于分割字符串
awk在写脚本的时候,用得比较多的是awk -F来切割字符串的场景。
1 | #默认情况下awk以空格作为分隔符 |
awk支持多个记录分隔符的写法
1 | #如何同时取出"age:23 color:red"里面的 “23”和“red”值呢? |
多个分隔符之间用管道符隔开
1 | #注意分割后的段数为NF |
本篇到此结束