Linux awk命令
作用
文本格式化
语法
awk options 'pattern {action}' file
选项的参数解释
-
options:选项,用于控制
awk的行为。 -
pattern:是用于匹配输入数据的模式。如果省略,则
awk将对所有行进行操作。 -
{action}:是在匹配到模式的行上执行的动作。如果省略,则默认动作是打印整行
options参数说明:
- -F <分隔符> 或 --field-separator=<分隔符>:指定输入字段的分隔符,默认就是空格。
- -v <变量名>=<值>:设置awk内部的值,可使用该选项将外部值传递给awk脚本中的变量。
- -f <脚本文件>:指定一个awk脚本文件。我们可以在指定文件中编写一个较大的awk脚本,然后通过-f 加载该脚本
- -V或者--version:显示awk的版本信息。
- -h 或者--help:显示 awk 的帮助信息,包括选项和用法示例。
以下是一些awk的常见用法:
打印整行:
awk '{print}' file打印特定列:
awk '{print $1, $2}' file[root@kylin awk]# awk '{print $1, $2}' awktest.txt asda adfsff asdas sdvgs njnk hsdh asdasdal adkl使用分隔符指定列:
awk -F ' ' '{print $1, $2}' file[root@kylin awk]# awk -F ' ' '{print $1, $3}' awktest.txt asda jppop asdas dsadfsdf njnk ipp asdasdal asdqvv打印行数:
awk '{print NR, $0}' file[root@kylin awk]# awk '{print NR, $0}' awktest.txt 1 asda adfsff jppop fdsd 2 asdas sdvgs dsadfsdf 3 njnk hsdh ipp fcsadfsdf gfgfgdfga 4 asdasdal adkl asdqvv tthgf打印满足条件的行
awk '/pattern/ {print NR, $0}' file如果我想找出包含 “njnk” 的行,以及行号
[root@kylin awk]# awk '/njnk/ {print NR, $0}' awktest.txt 3 njnk hsdh ipp fcsadfsdf gfgfgdfga计算列的总和
awk 'END {print NR}' file[root@kylin awk]# awk 'END{print NR}' awktest.txt 4打印最大值(第一列)
awk 'max < $1 {max = $1} END {print max}' fileawk 'BEGIN {max=-INF} {if ($1>max) max=$1} END {print max}' file初始化
max变量为无穷小-INF。-INF是awk中表示负无穷大的特殊值,这保证了任何数值都会大于它,从而允许第一次遇到的数值成为新的最大值。[root@kylin awk]# awk 'max < $1 {max = $1} END {print max}' awktest.txt njnk [root@kylin awk]# awk 'BEGIN {mak=-INF} {if ($1>max) max=$1} END {print max}' awktest.txt njnk格式化输出:
awk '{printf "%-10s %-10s\n", $1, $2}' file[root@kylin awk]# awk '{printf "%-10s %-10s\n", $1, $2}' awktest.txt asda adfsff asdas sdvgs njnk hsdh asdasdal adkl
基本用法
log.txt 文本内容:
ni yao gan sha 4
3 awk grep sed
who's a cool man
919 There are postgresql,mysql,gaussdb
用法1:
awk '{[pattern] action}' {filenames} # 行匹配语句 awk '' 只能用单引号
每行按空格或TAB分割,输出文本中的1、4项
[root@kylin awk]# awk '{print $1,$4}' log.txt
ni sha
3 sed
who's man
919 postgresql,mysql,gaussdb
格式化输出
[root@kylin awk]# awk '{printf "%-10s %30s\n",$1,$4}' log.txt
ni sha
3 sed
who's man
919 postgresql,mysql,gaussdb
"%-10s": 这是一个格式控制字符串,用于指定第一个输出字段的格式。%-10s表示输出一个字符串,占据10个字符宽度,左对齐(-表示左对齐)。如果字符串长度小于10,剩余的空间会被填充为默认的空格。%30s: 类似地,这表示输出第二个字段,占据30个字符宽度,右对齐(默认情况下printf是右对齐的)。如果字符串长度小于30,右侧会被填充为空格。\n: 这是一个换行符,用于在输出完一行数据后开始新的一行。
用法2:
awk -F #-F相当于内置变量FS, 指定分割字符
使用","分割
[root@kylin awk]# awk -F, '{print $1,$2}' log.txt
ni yao gan sha 4
3 awk grep sed
who's a cool man
919 There are postgresql mysql
或者使用内置变量
[root@kylin awk]# awk 'BEGIN{FS=","} {print $1,$2}' log.txt
ni yao gan sha 4
3 awk grep sed
who's a cool man
919 There are postgresql mysql
使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
[root@kylin awk]# awk -F '[ ,]' '{print $1,$2,$4}' log.txt
ni yao sha
3 awk sed
who's a man
919 There postgresql
用法3:
awk -v # 设置变量
[root@kylin awk]# awk -va=1 '{print $1,$1+a}' log.txt
ni 1
3 4
who's 1
919 920
[root@kylin awk]# awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
ni 1 nis
3 4 3s
who's 1 who'ss
919 920 919s
用法4:
awk -f {awk脚本} {文件名}
$ awk -f cal.awk log.txt
[root@kylin awk]# cat cal.awk
{print $1}
[root@kylin awk]# awk -f cal.awk log.txt
ni
3
who's
919
运算符
| 运算符 | 描述 |
|---|---|
| = += -= *= /= %= ^= **= | 赋值 |
| ?: | C条件表达式 |
| || | 逻辑或 |
| && | 逻辑与 |
| ~ 和 !~ | 匹配正则表达式和不匹配正则表达式 |
| < <= > >= != == | 关系运算符 |
| 空格 | 连接 |
| + - | 加,减 |
| * / % | 乘,除与求余 |
| + - ! | 一元加,减和逻辑非 |
| ^ *** | 求幂 |
| ++ -- | 增加或减少,作为前缀或后缀 |
| $ | 字段引用 |
| in | 数组成员 |
过滤第一列大于3的行
awk '$1 > 3'
[root@kylin awk]# awk '$1 > 3' log.txt
ni yao gan sha 4
who's a cool man
919 There are postgresql,mysql,gaussdb
过滤第一列等于3的行
[root@kylin awk]# awk '$1 == 3' log.txt
3 awk grep sed
过滤第一列大于3并且第二列等于'There'的行
[root@kylin awk]# awk '$1>3 && $2=="There" {print $0}' log.txt
919 There are postgresql,mysql,gaussdb
内建变量
| 变量 | 描述 |
|---|---|
| $n | 当前记录的第n个字段,字段间由FS分隔 |
| $0 | 完整的输入记录 |
| ARGC | 命令行参数的数目 |
| ARGIND | 命令行中当前文件的位置(从0开始算) |
| ARGV | 包含命令行参数的数组 |
| CONVFMT | 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组 |
| ERRNO | 最后一个系统错误的描述 |
| FIELDWIDTHS | 字段宽度列表(用空格键分隔) |
| FILENAME | 当前文件名 |
| FNR | 各文件分别计数的行号 |
| FS | 字段分隔符(默认是任何空格) |
| IGNORECASE | 如果为真,则进行忽略大小写的匹配 |
| NF | 一条记录的字段的数目 |
| NR | 已经读出的记录数,就是行号,从1开始 |
| OFMT | 数字的输出格式(默认值是%.6g) |
| OFS | 输出字段分隔符,默认值与输入字段分隔符一致。 |
| ORS | 输出记录分隔符(默认值是一个换行符) |
| RLENGTH | 由match函数所匹配的字符串的长度 |
| RS | 记录分隔符(默认是一个换行符) |
| RSTART | 由match函数所匹配的字符串的第一个位置 |
| SUBSEP | 数组下标分隔符(默认值是/034) |
[root@kylin awk]# awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s \n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "-------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}' log.txt
FILENAME ARGC FNR FS NF NR OFS ORS RS
-------------------------------------------
log.txt 2 1 5 1
log.txt 2 2 4 2
log.txt 2 3 4 3
log.txt 2 4 4 4
[root@kylin awk]# awk -F^ 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s \n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "-------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}' log.txt
FILENAME ARGC FNR FS NF NR OFS ORS RS
-------------------------------------------
log.txt 2 1 ^ 1 1
log.txt 2 2 ^ 1 2
log.txt 2 3 ^ 1 3
log.txt 2 4 ^ 1 4
正则表达式
# 输出第二列包含 "a",并打印第二列与第四列
[root@kylin awk]# awk '$2 ~ /a/ {print $2,$4}' log.txt
yao sha
awk sed
a man
~ 表示模式开始。// 中是模式
awk 脚本
关于 awk 脚本,我们需要注意两个关键词 BEGIN 和 END。
- BEGIN{ 这里面放的是执行前的语句 }
- END {这里面放的是处理完所有的行后要执行的语句 }
- {这里面放的是处理每一行时要执行的语句}
创建测试文件如下:
Marry 2143 78 84 77 Jack 2321 66 78 45 Tom 2122 48 77 71 Mike 2537 87 97 95 Bob 2415 40 57 62
cal.awk脚本如下:
[root@kylin awk]# cat cal.awk
#!/bin/awk -f
BEGIN {
math = 0
english = 0
computer = 0
print "NAME NO MATH ENGLISH COMPUTER TOTAL\n"
print "--------------------------------------------------------------\n"
}
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n",math,english,computer
}
END {
print "--------------------------------------------------------------\n"
printf " TOTAL:%10d %8d %8d \n", math, english, computer
printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}
执行结果
[root@kylin awk]# awk -f cal.awk score.txt
NAME NO MATH ENGLISH COMPUTER TOTAL
--------------------------------------------------------------
Marry 2143 78 84 77 239
Jack 2321 66 78 45 189
Tom 2122 48 77 71 196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
--------------------------------------------------------------
TOTAL: 319 0 350
AVERAGE: 63.80 0.00 70.00
[root@kylin awk]# vim cal.awk
[root@kylin awk]# awk -f cal.awk score.txt
NAME NO MATH ENGLISH COMPUTER TOTAL
--------------------------------------------------------------
Marry 2143 78 84 77 239
Jack 2321 66 78 45 189
Tom 2122 48 77 71 196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
--------------------------------------------------------------
TOTAL: 319 393 350
AVERAGE: 63.80 78.60 70.00