Linux之awk命令学习笔记
前言
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
语法
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
- [-F|-f|-v] 大参数,-F指定分隔符(字符串或正则表达式),-f调用脚本,-v定义变量 var=value
- ’ ’ 引用代码块
- BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
- // 匹配代码块,可以是字符串或正则表达式
- {} 命令代码块,包含一条或多条命令
- ; 多条命令使用分号分隔
- END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
基本用法
test.txt文本内容如下:
2 this is a awk test
3 Are you like XDU
This's a test
10 There are vivado,hls,modelsim,tcl
用法一:
awk '{[pattern] action}' {filenames} # 行匹配语句 awk '' 只能用单引号
实例:
awk '{print $1,$4}' test.txt # 每行按空格或TAB分割,输出文本中的1、4项
#output:
2 a
3 like
This's
10 vivado,hls,modelsim,tcl
awk '{printf "%-8s %-10s\n",$1,$4}' test.txt #格式化输出,按一定的间距输出
#output:
2 a
3 like
This's
10 vivado,hls,modelsim,tcl
用法二:
awk -F #-F相当于内置变量FS, 指定分割字符
实例:
awk -F, '{print $1,$2}' test.txt #使用","分割
#output:
2 this is a awk test
3 Are you like XDU
This's a test
10 There are vivado hls
awk 'BEGIN{FS=","}{print $1,$2}' test.txt # 或者使用内建变量FS进行分割
#output:
2 this is a awk test
3 Are you like XDU
This's a test
10 There are vivado hls
awk -F '[ ,]' '{print $1,$2,$5}' test.txt #使用多个分割符,对空格和","均进行分割操作
#output:
2 this awk
3 Are XDU
This's a
10 There hls
用法三:
awk -v # 设置变量
实例:
awk -v a=1 '{print $1,$1+a}' test.txt #设置初始变量为a,且a=1
#output:
2 3
3 4
This's 1
10 11
awk -v a=1 -v b=s '{print $1,$1+a,$1b}' test.txt #设置初始字符变量为b,注意字符变量不能用于运算
#output:
2 3 2s
3 4 3s
This's 1 This'ss
10 11 10s
用法四:
awk -f {awk脚本} {文件名}
实例:
awk -f cal.awk test.txt
运算符
运算符 | 描述 |
---|---|
= += -= *= /= %= ^= **= | 赋值 |
?: | C条件表达式 |
|| | 逻辑或 |
&& | 逻辑与 |
~ 和 !~ | 匹配正则表达式和不匹配正则表达式 |
< <= > >= != == | 关系运算符 |
空格 | 连接 |
+ - | 加,减 |
* / % | 乘,除与求余 |
+ - ! | 一元加,减和逻辑非 |
^ *** | 求幂 |
++ – | 增加或减少,作为前缀或后缀 |
$ | 字段引用 |
in | 数组成员 |
实例:
awk '$1>2' test.txt #输出第一列大于2的行
#output:
3 Are you like XDU
This's a test
10 There are vivado,hls,modelsim,tcl
awk '$1==2 {print $1,$3}' test.txt #找到第一列等于2的行,并打印第一和第三个字符(以空格或者TAB分隔开)
#output:
2 is
awk '$1>2 && $2=="Are" {print $1,$3}' test.txt #找到第一列大于2并且第二列等于"Are"的行
#output:
3 you
使用正则,字符串匹配
awk '$2 ~ /th/ {print $2,$4}' test.txt # 找到第二列包含 "th"的行,并打印该行的第二列与第四列
#output:
this a
~表示模式开始。//中是模式。
awk '/re/' test.txt #输出包含"re"的行
#output:
3 Are you like XDU
10 There are vivado,hls,modelsim,tcl
忽略大小写
awk 'BEGIN{IGNORECASE=1}/THIS/' test.txt #打印含"THIS"的行,忽略大小写区别
#output:
2 this is a awk test
This's a test
模式取反
awk '$2 !~ /th/ {print $2,$4}' test.txt #取出第二列不含"th"的行,并打印出该行的第二和第四列
#output:
Are like
a
There vivado,hls,modelsim,tcl
awk '! /th/ {print $2,$4}' test.txt
#output:
Are like
a
There vivado,hls,modelsim,tcl
awk脚本
关键词BEGIN和AND
- BEGIN{ 这里面放的是执行前的语句 }
- END {这里面放的是处理完所有的行后要执行的语句 }
- {这里面放的是处理每一行时要执行的语句}
awk脚本如下:
$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf "---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf "---------------------------------------------\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
}
执行结果如下:
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