awk
awk是一个强大的linux命令,有强大的文本格式化的能力,好比奖一些文本数据格式化成妆业的excel表的样式。
awk早期在Unix上实现,我们用的awk是gawk,是GUN awk的意思
awk更像是一门编程语言,支持条件判断、数组、循环等功能。
awk语法
awk [option] 'pattern[action]' file ...
awk 参数 '条件动作' 文件
Action指的是动作,awk擅长文本格式化,且输出格式化后的结果,因此常用的动作是print和printf。
输出内容
# 输出整行数据
awk '{print $0}' tmp.txt
# 输出第一列数据
awk '{print $1}' tmp.txt
awk内置变量
内置变量 | 解释 |
---|---|
$n | 指定分隔符后,当前记录的第n个字段 |
$0 | 完整的输入记录 |
FS | 字段分隔符,默认是空格 |
NF(number of filed) | 分割后,当前行一共有多少个字符 |
NR(Number of records) | 当前记录数,行数 |
更多内置变量可以man手册查看 | man awk |
一次性输出多列
# 输出第一列和第二列
awk '{print $1, $2}' tmp.txt
自定义输出内容
awk 必须 外层单引号,内层双引号
内置变量 $1 $2 都不得加双引号,否则会识别为文本,尽量别加引号
awk '{print "第一列:" $1, "第二列:" $2}' tmp.txt
awk参数
参数 | 解释 |
---|---|
-F | 指定分割字段符 |
-v | 定义或修改一个awk内部的变量 |
-f | 从脚本文件中读取awk命令 |
实践
# 显示文件第五行
awk 'NR==5{print $0}' tmp.txt
# 显示文件第二行和第五行
awk 'NR==2,NR==5{print $0}' tmp.txt
# 显示文件第二行到第五行
awk 'NR==2,NR==5' tmp.txt
# 给每一行添加行号
awk '{print NR,$0}' tmp.tx
# 显示37-40行且输出行号
awk 'NR=37,NR==40{print NR,$0}' tmp.txt
# 显示tmp.txt文件的第一列,倒数第二和最后一列
awk '{print $1,$(NF-1),$(NF)}'
awk分隔符
awk的分隔符有两种
- 输入分隔符,awk默认是空格,空白字符,英文是field separator,变量名是FS
- 输出分隔符,output field separator,简称OFS
FS输入分隔符
awk逐行处理文本时,把
awk -F ":" '{print $1}' tmp.txt
awk -v FS=":" '{print $1}' tmp.txt
输出分隔符
# 输出分隔符
awk -F ":" '{print $1,$NF}' tmp.txt # ”,“默认是输出空格
awk -F ":" -v OFS="===" '{print $1,$NF}' tmp.txt # 将输出分隔符改成 ===
awk -F ":" -v OFS="\t" '{print $1,$NF}' tmp.txt # 将输出分隔符改成 \t
awk变量
- 内置变量
- 自定义变量
内置变量
内置变量 | 解释 |
---|---|
FS | 输入字段分隔符,默认为空白字符 |
OFS | 输出字段分隔符,默认为空白字符 |
RS | 输入记录分隔符(输入换行符),指定输入时的换行符 |
ORS | 输出记录分隔符(输出换行符),指定输出时指定符号替换换行符 |
NF | 字段数量 |
NR | 行号,当前处理的文本行的行号 |
FNR | 各文件分别计数的行号 |
FILENAME | 当前文件名 |
ARGC | 命令行参数的个数 |
ARGV | 数组,保存的是命令行所给定的各参数 |
NR,NF,FNR
- awk的内置变量NR、NF是不用添加$符号的
- 而 $0 $1 $2 ¥3 … 是需要添加 $ 符号的
cat tmp.txt
awk -v FS=":" '{print NR,NF,$1}' tmp.txt
awk -v FS=":" '{print NR,$(NF-1)}' tmp.txt
处理多文件显示行号
# 显示多个文件
awk '{print $0}' tmp1.txt tmp1.txt
# 显示行号
awk '{print NR,$0}' tmp1.txt tmp2.txt
# 各文件分别显示行号
awk '{print FNR,$0}' tmp1.txt tmp2.txt
ORS
输出分隔符
默认使用换行符
awk -v ORS="---" '{print NR,$0}' tmp.txt
# 把换行符修改成---
FILENAME
awk '{print FILENAME,$0}' tmp.txt
ARGC,ARGV
awk '{print $1}' tmp.txt
awk 'BEGIN{print "laomao学awk"} {print $0}' tmp.txt
awk 'BEGIN{print "laomao学awk"} {print $0} {print ARGV[0],ARGV[1]}' tmp.txt tmp2.txt
# ARGV[0]:awk ARGV[1]:tmp.txt ARGV[2] tmp2.txt
自定义变量
awk -v name="laomao" 'BEGIN{print "who are you?",name}'
# who are you? laomao
#间接引用shell变量
name="laomao"
awk -v myname=$name 'BEGIN{print myname}'
awk格式化输出
printf和print的区别
printf 格式化输出
print 一般输出
printf需要指定格式,而print不需要
printf 不会自动打印换行符 \n
format格式的指示符都是以%开头的,后跟一个字符:
- %c:显示字符的ASCII码;
- %d,%i:十进制整数;
- %e,%E:科学计数法显示数值;
- %f:显示浮点数;
- %g,%G:以科学计数法的格式活浮点数的格式显示数值;
- %s:显示字符串;
- %u:无符号整数;
- %%显示%本身。
printf修饰符:
- - 左对齐,默认右对齐;
- + 显示数值符号; printf “%+d”
awk '{printf "%s\n",$0}' tmp.txt
# linux中
printf "%s\n" a,b,c,d,e
## 输出
a
b
c
d
e
# awk中
awk 'BEGIN{printf "%d\n%d\n%d\n%d\n",1,2,3,4}' # %d个数必须和字符对应
## 输出
1
2
3
4
awk模式pattern
awk是按行处理文本,特殊的pattern:BEGIN 和 END
- BEGIN模式是处理文本之前需要执行的操作;
- END模式是处理完所有行之后执行的操作。
awk 'BEGIN{print "start..."}{print $0}END{print "process success!"}' tmp.txt
pattern可以看作条件
awk 'NR==2{print $0}' tmp.txt
awk 'NR<4{print $0}' tmp.txt
符号
关系运算符 | 解释 |
---|---|
< | 小于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
> | 大于 |
>= | 大于等于 |
~ | 匹配正则 |
!~ | 不匹配正则 |
示例
awk 'BEGIN{print "start..."}{print $0}END{print "process success!"}' tmp.txt
awk '{print $1}' log.wf | sort -n | uniq | wc -l
sort -n # 数字从大到小排序
sort -nr # 从小到大排序
head -10 # 取十个数据
wc -l # 统计行数