10.awk

三剑客:grep、sed、awk

awk:三个人写的名字字母拼接,一种小型编程语言

作用:

  • 取行
  • 取列
  • 模糊过滤
  • 数据统计 数据运算
  • 支持基本for循环if判断数组等
1
2
3
4
语法结构:
awk '模式' 文件 # 没加动作,默认输出动作
awk '模式{print}' 文件 # 模式+动作,加不加print默认相同结果
命令输出|awk '模式'

按行查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sed -n '3p' file # sed的指定3行,grep不行

# awk输出指定第3行,NR是内置变量(记录着文件中每行的行号)
awk 'NR==3' file

awk 'NR>3' file # 大于第三行

awk 'NR>=3' file # 大于等于第三行

awk 'NR!=3' file # 不等于第三行

awk 'NR >2 && NR <5' file # 大于2小于5

awk 'NR <2 || NR > 4' file # 小于2或者大于4

模糊过滤(行)

1
2
3
4
5
6
7
8
9
10
grep '' 文件
sed -n '/内容/p' 文件
awk '/内容/' 文件
awk '//,//' 文件

awk '/root/' test.txt # 找到包含root的行

awk '/h$/' test.txt # 查找h结尾的行

awk '/^1/,/^2/' test.txt # 区间范围1开头的到2开头的

注:

扩展正则

  • grep -E 或 egrep
  • sed -r
  • awk

awk取列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
语法结构:
awk '{print $n}' file # 不能用""
$0: 内置变量,每行的全部
$1: 第一列
$n: 第n列(默认以tab键和空格为分割符
可以这么理解:每行每行的处理,按tab或空格分割存入${1..n}

awk '{print $1}' file # 输出文件第一列

awk '{print $1,$2}' file # ,就空格分开

# 所有的字符在awk空当做变量
awk '{print $1" "$2}' file # 中间加一个" "字符串


# 输出最后一列的列号#
awk '{print NF}' file # NF是内置变量,表示每行的最后一列号

# awk内默认字符串看做变量,那么显示文件最后一列就可以
awk '{print $NF}' file


# awk取倒数第二lie
awk '{print $(NF-1)}' file # 取出倒数第二例



awk指定分割符,-F
# 例如:
-F: # 通过:分割
-F ":" # 通过:分割

awk -F: '{print $5}' /etc/passwd # 按:分割查看passwd的用户备注信息

awk -F "[:/]" '{print $5,$6,$7}' test.txt # 通过:或者/任意单个进行分割

awk -F "[:/]+" '{print $5,$6,$7}' test.txt # 通过:和/任意连续一个或者一个以上进行分割

awk模式+动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
awk -F: 'NR==3{print $5 }' test.txt # 第三行,:分割的第5列

awk -F "[ :]" '{print $2"\t"$NF }' test.txt

df -h |awk '/sda/{print $2}' # df -h查找sda行输出第2列

df -h |sed -n '/sda/p'|awk '{print $4}'

df -h |awk 'NR>5&&NR<9{print $1,$NF}'


# 字符串匹配
awk -F: '$3=="1000"' /etc/passwd

awk -F: '$NF=="/bin/bash"' /etc/passwd

# 找出第二列匹配的行
awk '$2 ~ /^o/' test.txt # 匹配第二列以o开头的

awk -F: '$2 ~ /^o/' test.txt # 匹配第二列以o开头的

awk -F: '$3 >= 1000' /etc/passwd

eg:

1
2
# 开始读取文件之前输出一个开始,结束之后输出一个结束
awk -F: 'BEGIN{print "开始"}{print $1}END{print "结束"}' /etc/passwd