目录
[4.3、查找行首"^"与行尾字符""](#4.3、查找行首“^”与行尾字符“”)
[2.3、将没有出现 root 的行取出来](#2.3、将没有出现 root 的行取出来)
[3.1.2、显示范围 行号](#3.1.2、显示范围 行号)
[5.3、BEGIN END 运算](#5.3、BEGIN END 运算)
[5.5、awk if语句](#5.5、awk if语句)
[5.6、BEGIN END 循环](#5.6、BEGIN END 循环)
一、正则表达式
1、正则表达式定义
1.1正则表达式的概念及作用
正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于描述字符串模式的工具。它是一种强大的文本处理工具,用于查找、匹配、替换或验证字符串中的文本数据。
正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
1.2、正则表达式的工具
- grep
- sed
- awk
- egrep
1.3、正则表达式的组成
正则表达式---通常用于判断语句中,用来检查某一字符串是否满足某一格式
- 普通字符:普通字符包括大小写字母、数字、标点符号及一些其他符号
- 元字符:元字符是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式
LINUX 中常用的有两种正则表达式引擎
- 基础正则表达式:BRE
- 扩展正则表达式: ERE
2、基础正则表达式
支持的工具
- grep
- egrep
- sed
- awk
转义字符:
符号 | 描述 |
---|---|
\ | 转义符,将特殊字符进行转义,忽略其特殊意义。 |
^ | 匹配行首,匹配字符串的开始。 |
$ | 匹配行尾,匹配字符串的结尾。 |
. | 匹配除换行符 \r\n 之外的任意单个字符。 |
[list] | 匹配 list 列表中的一个字符。 |
[^list] | 匹配任意不在 list 列表中的一个字符。 |
* | 匹配前面子表达式 0 次或者多次。 |
\{n\} | 匹配前面的子表达式 n 次。 |
\{n,\} | 匹配前面的子表达式不少于 n 次。 |
\{n,m\} | 匹配前面的子表达式 n 到 m 次。 |
注意:
- egrep、awk使用{n}、{n, }、{n, m}匹配时"{}"前不用加"\"
- egrep -E -n 'wo{2}d' test.txt //-E 用于显示文件中符合条件的字符
- egrep -E -n 'wo{2,3}d' test.txt
3、扩展正则表达式
通常情况下会使用基础正则表达式就已经足够了,但有时为了简化整个指令,需要使用 范围更广的扩展正则表达式。
支持工具
- egrep
- awk
常用的几个扩展正则表达式元字符
符号 | 描述 |
---|---|
+ | 重复一个或者一个以上的前一个字符。 |
? | 零个或者一个的前一个字符。 |
| | 使用或者(or)的方式找出多个字符。 |
() | 查找"组"字符串。 |
()+ | 辨别多个重复的组。 |
例如:
①、
|---|-------------------|
| + | 重复一个或者一个以上的前一个字符。 |
②、
|---|---------------|
| ? | 零个或者一个的前一个字符。 |
③、
|----|--------------------|
| | | 使用或者(or)的方式找出多个字符。 |
④、
|----|-----------|
| () | 查找"组"字符串。 |
⑤、
|-----|-----------|
| ()+ | 辨别多个重复的组。 |
4、元字符操作
4.1、查找特定字符
查找文件中的字符 "the"
反向选择:查找文件中不包含"the"
4.2、利用中括号"[]"来查找集合字符
- 查找文件中"shirt"与"short"这两个字符串
- 查找包含重复单个字符"oo"时
- 查找"oo"前面不是"w"的字符串
- 查找"oo"前面不是小写字母的字符串
"a-z"表示小写字母,大写字母则通过"A-Z"表示。
- 查找文件中包含数字的行
4.3、查找行首"^"与行尾字符"$"
基础正则表达式包含两个定位元字符:"^"(行首)与"$"(行尾)。在上面的示例中, 查询"the"字符串时出现了很多包含"the"的行,如果想要查询以"the"字符串为行首的行,则可以通过"^"元字符来实现。
- 例如:
查询以小写字母开头的行可以通过"^[a-z]"规则来过滤,查询大写字母开头的行则使用
"^[A-Z]"规则,若查询不以字母开头的行则使用"^[^a-zA-Z]"规则。
- 例如:
以小写字母开头
- 以大写字母开头
- 以字母开头
"^"符号在元字符集合"[]"符号内外的作用是不一样的,在"[]"符号内表示反向选择,在"[]" 符号外则代表定位行首。反之,若想查找以某一特定字符结尾的行则可以使用"$"定位符。
- 例如:
- 查询空白行
4.4、查找任意一个字符"."与重复字符"*"
前面提到,在正则表达式中小数点(.)也是一个元字符,代表任意一个字符。例如执行以下命令就可以查找"w??d"的字符串,即共有四个字符,以 w 开头 d 结尾。
"*"代表的是重复零个或多个前面的单字符。
4.5、查找连续字符范围"{}"
在上面的示例中,使用了"."与"*"来设定零个到无限多个重复的字符,如果想要限制一个范围内的重复的字符串该如何实现呢?例如,查找三到五个 o 的连续字符,这个时候就需要使用基础正则表达式中的限定范围的字符"{}"。因为"{}"在 Shell 中具有特殊意义,所以在使用"{}"字符时,需要利用转义字符"\",将"{}"字符转换成普通字符。"{}"字符的使用方法如下所示。
①、查询两个 o 的字符。
②、查询以 w 开头以 d 结尾,中间包含 2~7个 o 的字符串。
③、查询以 w 开头以 d 结尾,中间包含 2 个或 2 个以上 o 的字符串。
二、、grep语句
1、grep用法
grep
是用于在文件或文本输入中搜索匹配特定模式的行的工具,并输出包含该模式的行。它非常适合用于过滤和查找文本中的特定字符串或正则表达式。
- 语法格式
cpp
grep [选项]... 查找条件 目标文件
- 使用参数
选项 | 描述 |
---|---|
-E | 开启扩展正则表达式 (Extended Regular Expressions)。允许使用更复杂的正则表达式。 |
-c | 计算匹配到的行数。 |
-i | 忽略大小写的不同(大小写视为相同)。 |
-o | 仅显示匹配到的字符串,而不是整行。 |
-v | 反向选择,显示不包含搜索字符串的行。 |
--color=auto | 为匹配的字符串部分添加颜色显示。 |
-n | 显示匹配行的行号。 |
2、grep案例
2.1、统计root字符总行数
cpp
root@localhost opt]# grep -c root /etc/passwd
2.2、不区分大小写查找the所有的行
cpp
[root@localhost opt]# grep -i "the" cxc.txt
2.3、将没有出现 root 的行取出来
cpp
[root@localhost opt]# cat 222.txt
[root@localhost opt]# grep -v root /opt/222.txt
2.4、过滤出IP
cpp
[root@localhost opt]# ifconfig ens33 |grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+"
三、sed命令
1、sed概述
1.1、sed定义
sed(Stream EDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出处理的某些行。sed也可以在无交互的情况下实现相当复杂的文本处理操作,被广泛应用于Shell脚本中,用以完成各种自动化处理任务。
1.2、sed工作原理
读入新的一行内容到缓存空间;
从指定的操作指令中取出第一条指令,判断是否匹配pattern;
如果不匹配,则忽略后续的编辑命令,回到第2步继续取出下一条指令;
如果匹配,则针对缓存的行执行后续的编辑命令;完成后,回到第2步继续取出下一条指令;
当所有指令都应用之后,输出缓存行的内容;回到第1步继续读入下一行内容;
当所有行都处理完之后,结束;
2、sed基本用法
- 使用格式
cpp
sed [选项] '操作' 参数
sed [选项] -f scriptfile 参数
- 常用选项
选项 | 说明 |
---|---|
-e 或 --expression= | 用指定命令或者脚本来处理输入的文本文件。 |
-f 或 --file= | 用指定的脚本文件来处理输入的文本文件。 |
-h 或 --help | 显示帮助信息。 |
-n、--quiet 或 --silent | 仅显示处理后的结果,不输出原始输入。 |
-i[.bak] | 直接编辑文本文件。如果指定 .bak,会创建备份文件。 |
-r 或 -E | 使用扩展正则表达式(Extended Regular Expressions, ERE)。 |
-s | 将多个文件视为独立文件,而不是单个连续的长文件流。 |
- sed常用命令动作
选项 | 说明 |
---|---|
p | 打印输出 |
d | 删除指定行 |
i | 在指定行之前插入内容 |
a | 在指定行后面插入内容 |
c | 替换指定行所有内容 |
s | 搜索替换 |
3、sed具体操作
3.1、打印输出
cpp
[root@localhost home]# sed '' 123.txt
[root@localhost home]# sed 'p' 123.txt
[root@localhost home]# sed -n 'p' 123.txt
3.1.2、显示范围 行号
cpp
[root@localhost home]# sed -n '1p' 123.txt
[root@localhost home]# sed -n '1,3p' 123.txt
[root@localhost home]# sed -n '1p;3p;5p' 123.txt
[root@localhost home]# sed -n '1,+3p' 123.txt
3.1.3、奇偶数表示
cpp
[root@localhost home]# sed -n '1~2p' 123.txt
[root@localhost home]# sed -n '2~2p' 123.txt
[root@localhost home]# sed -n '2~3p' 123.txt
[root@localhost home]# sed -n '$p' 123.txt
[root@localhost home]#
[root@localhost home]# sed -n '/cxc/p' 123.txt
[root@localhost home]# sed -n '/haha$/p' 123.txt
cpp
[root@localhost home]# sed -n '/[0-9]/p' 456.txt
[root@localhost home]# sed -n '/^root/p' 456.txt
[root@localhost home]# sed -n '1!p' 456.txt
[root@localhost home]# sed -n '/root/!p' 456.txt
[root@localhost home]# sed -n '$=' 456.txt
sed默认不支持扩展正则,如果要支持,需要加-r选项
3.2、增加内容
cpp
[root@localhost home]# sed '2ihello world' 456.txt
cpp
[root@localhost home]# sed '4ihello\nworld' 456.txt
cpp
[root@localhost home]# sed '1ahello world' 456.txt
cpp
[root@localhost home]# sed '$ahello world' 456.txt
注意:a或者i后面的所有内容都会被理解为需要添加的内容
3.3、删除
cpp
[root@localhost home]# sed '1d' 123.txt //删除第一行
2 zmx:oppo
3 root:root
4 wjh:123
5 jjg:456
6 jhw:789
7 njnj:kgc
8 ky37:lhai
9 kfc:ail
10 mdl:keyi
[root@localhost home]# sed '1,3d' 123.txt //删除一到三行
4 wjh:123
5 jjg:456
6 jhw:789
7 njnj:kgc
8 ky37:lhai
9 kfc:ail
10 mdl:keyi
[root@localhost home]# sed '/123/d' 123.txt //删除带有123的行
1 cxc:haha
2 zmx:oppo
3 root:root
5 jjg:456
6 jhw:789
7 njnj:kgc
8 ky37:lhai
9 kfc:ail
10 mdl:keyi
[root@localhost home]#
3.4、替换
- 常用选项
选项 | 说明 |
---|---|
g | 行内全局替换,替换行中的所有匹配项 |
p | 显示替换成功的行 |
w /PATH/FILE | 将替换成功的行保存至指定的文件中 |
I, i | 忽略大小写(i 是基本正则表达式的选项,I 是扩展正则表达式的选项) |
cpp
[root@localhost home]# sed '/^root/ckgc' 456.txt //以root开头的行替换成kgc
cxc:haha
zmx:oppo
kgc //已替换
wjh:123
jjg:456
jhw:789
njnj:kgc
ky37:lhai
kfc:ail
mdl:keyi
[root@localhost home]#
[root@localhost home]# sed '/haha/cnjzb' 456.txt //带有haha字符的行替换成njzb
njzb //已替换
zmx:oppo
root:root
wjh:123
jjg:456
jhw:789
njnj:kgc
ky37:lhai
kfc:ail
mdl:keyi
njzb //已替换
[root@localhost home]#
这里没有真的改变文件内容,只是输出到屏幕,如果想要真的替换,需要用-i选项,建议用-i之前对原文 件进行备份
3.5、插入文件
cpp
[root@localhost home]# sed '3r /etc/hosts' 456.txt //将/etc/hosts文件插入到第三行下面
cxc:haha
zmx:oppo
root:root
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
wjh:123
jjg:456
jhw:789
njnj:kgc
ky37:lhai
kfc:ail
mdl:keyi
lala:haha
[root@localhost home]# sed '$r /etc/hosts' 456.txt //插入到最后一行
cxc:haha
zmx:oppo
root:root
wjh:123
jjg:456
jhw:789
njnj:kgc
ky37:lhai
kfc:ail
mdl:keyi
lala:haha
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@localhost home]#
3.6、同时编辑
sed支持一个或多个-e参数
cpp
//提取第一行和第三行
[root@localhost home]# sed -n -e '1p' -e '3p' 123.txt
1 cxc:haha
3 root:root
[root@localhost home]# sed -ne '1p' -ne '3p' 123.txt
1 cxc:haha
3 root:root
[root@localhost home]#
3.7、读取完退出
(注意:q不要和-i一起使用,以免覆盖源文件)
正常情况下sed会在读取完所有数据行之后退出,但是我们可以随时使用q指令来提前退出sed
cpp
[root@localhost home]# sed '3q' 123.txt //表示仅显示处理后的结果
1 cxc:haha
2 zmx:oppo
3 root:root
[root@localhost home]#
四、awk命令
1、awk定义
20世纪70年代诞生于贝尔实验室,现在centos7用的是gawk之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
- AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
- 它是专门为文本处理设计的编程语言,也是行处理软件,通常用于扫描、过滤、统计汇总工作
- 数据可以来自标准输入也可以是管道或文件
有多种版本:
- AWK:原先来源于 AT & T 实验室的的AWK
- NAWK:New awk,AT & T 实验室的AWK的升级版
- GAWK:即GNU AWK。所有的GNU/Linux发布版都自带GAWK,它与AWK和NAWK完全兼容
Linux中现在使用的是gawk
2、工作原理
当读到第一行时,匹配条件,然后执行指定动作,再接着读取第二行数据处理,不会默认输出 如果没有定义匹配条件默认是匹配所有数据行。
awk隐含循环,条件匹配多少次动作就会执行多少次 逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按 模式或者条件执行编辑命令。
3、工作流程
3.1、运行模式
正则表达式 : /root/ 匹配含有 root 的行 /*.root/
关系表达式: < > && || + *
匹配表达式: ~ !~ 动作:
变量 命令 内置函数 流控制语句它的语法结构如下:
3.2、执行流程
BEGIN 语句设置计数和打印头部信息,在任何动作之前进行
END 语句输出统计结果,在完成动作之后执行
AWK执行的流程非常简单:读(Read)、执行(Execute)与重复(Repeat)。
下面的流程图描述出 了AWK的工作流程:
①、开始块(BEGIN block):
顾名思义,开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次。一般情况 下,我们在开始块中初始化一些变量。BEGIN是AWK的关键字,因此它必须是大写的。不过,开始块部 分是可选的,你的程序可以没有开始块部分。
②、主体块(Body Block):
对于每一个输入的行,都会执行一次主体部分的命令。默认情况下,对于输入的每一行,AWK都会执行 命令。注意:在主体块部分,没有关键字存在。
③、结束块(END Block):
它是在程序结束时执行的代码。END也是AWK的关键字,它也必须大写。与开始块相似,结束块也是可选的。
4、基本语法
4.1、命令格式
cpp
awk 选项' 模式或条件{操作}' 文件1 文件2 ...
awk -f 脚本文件 文件1 文件2 ..
AWK 支持两种不同类型的变量:内建变量(可直接使用),自定义变量awk 内置变量(预定义变量)
变量 | 解释 |
---|---|
FS | 指定每行文本的字段分隔符,默认为空格或制表位 |
NF | 当前处理的行的字段个数,对应于当前的字段数(列的个数) |
NR | 当前处理的行的行号(序数),对应于当前的行号 |
$0 | 当前处理的行的整行内容 |
$n | 当前处理行的第 n 个字段(第 n 列) |
FILENAME | 被处理的文件名(当前输入文件的名) |
FNR | 各文件分别计数的行号 |
OFS | 输出字段分隔符,默认值是一个空格 |
ORS | 输出记录分隔符,默认值是一个换行符 |
RS | 行分隔符,默认是换行符 |
5、实验操作
5.1、内建变量
awk 包含几个特殊的内建变量(可直接用)如下所示:
变量 | 解释 |
---|---|
FS | 指定每行文本的字段分隔符,默认为空格或制表位 |
NF | 当前处理的行的字段个数 |
NR | 当前处理的行的行号(序数) |
$0 | 当前处理的行的整行内容 |
$n | 当前处理行的第 n 个字段(第 n 列) |
FILENAME | 被处理的文件名 |
RS | 行分隔符 |
cpp
[root@localhost opt]# awk '{print}' //再打印一边
123
123
456
456
[root@localhost opt]# awk '{print"hellow"}' //字符串需要添加双引号
123
hellow
456
hellow
[root@localhost opt]# cat /etc/passwd |head -10 > zz.txt
[root@localhost opt]#
[root@localhost opt]# awk -F: '{print $1}' zz.txt //自定义冒号为分隔符显示分隔之后的第一列
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
[root@localhost opt]# awk -F: '{print $1,$2}' zz.txt //逗号有空格效果,打印第一列和第二列
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
operator x
[root@localhost opt]# awk -F: '{print $1" "$2}' zz.txt //空格需要使用双引号括起来
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
operator x
[root@localhost opt]# awk -F: '{print $1"\t"$2}' zz.txt //用制表符作为分隔符输出
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
operator x
[root@localhost opt]# awk -F[:/] '{print $4}' zz.txt //定义多个分隔符
0
1
2
4
7
0
0
0
12
0
[root@localhost opt]#
5.2、内置变量
awk常用内置变量:$1、$2、NF、NR、$0
- $1:代表第一列
- $2:代表第二列以此类推
- $0:代表整行
- NF:一行的列数
- NR:行数
cpp
[root@localhost opt]# awk -F: '/root/{print $0}' zz.txt //打印包含root的整行内容
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost opt]# awk -F: '/root/{print $1,$6}' zz.txt //打印包含root的第一列和第六列
root /root
operator /root
[root@localhost opt]# awk '/root/' zz.txt //打印包含root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost opt]# awk -F[:/] '{print NF}' zz.txt //以:/分割,打印每一行的列数
10
10
10
11
12
10
10
10
12
10
[root@localhost opt]# awk -F[:/] '{print NR}' zz.txt //显示行号
1
2
3
4
5
6
7
8
9
10
[root@localhost opt]# awk -F: '{print NR,$0}' zz.txt //每一行显示行号
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost opt]# awk 'NR==2' zz.txt
bin:x:1:1:bin:/bin:/sbin/nologin
[root@localhost opt]# awk -F: 'NR==2{print $1}' zz.txt //打印第二行的第一列
bin
[root@localhost opt]# awk -F: '{print $NF}' zz.txt //打印最后一列
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologi
/sbin/nologin
[root@localhost opt]# awk 'END{print NR}' zz.txt //打印总行数
10
[root@localhost opt]# awk 'END{print $0}' zz.txt
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost opt]# awk -F: '{print"当前有"NF"列"}' zz.txt //打印列数
当前有7列
当前有7列
当前有7列
当前有7列
当前有7列
当前有7列
当前有7列
当前有7列
当前有7列
当前有7列
[root@localhost opt]# awk -F: '{print"第"NR"行有"NF"列"}' zz.txt //打印每一行有多少列
第1行有7列
第2行有7列
第3行有7列
第4行有7列
第5行有7列
第6行有7列
第7行有7列
第8行有7列
第9行有7列
第10行有7列
[root@localhost opt]#
5.3、BEGIN END 运算
逐行执行开始之前执行什么任务,结束之后再执行什么任务,用BEGIN、END
BEGIN一般用来做初始化操作,仅在读取数据记录之前执行一次
END一般用来做汇总操作,仅在读取完数据记录之后执行一次
cpp
[root@localhost opt]#
[root@localhost opt]# awk 'BEGIN{x=10;print x}'
10
[root@localhost opt]# awk 'BEGIN{x=10;print x+5}'
15
[root@localhost opt]# awk 'BEGIN{x=10;x++;print x+1}' //BEGIN在处理文件之前,所以后面不跟
文件名也不影响
12
[root@localhost opt]# awk 'BEGIN{print x+1}' //不指定初始值,初始值就为0
1
[root@localhost opt]# awk 'BEGIN{print 3.5+2.5}' //小数也可以运算
6
[root@localhost opt]# awk 'BEGIN{print 6-2}'
4
[root@localhost opt]# awk 'BEGIN{print 2*6}'
12
[root@localhost opt]# awk 'BEGIN{print 3^2}'
9
[root@localhost opt]# awk 'BEGIN{print 1/2}'
0.5
[root@localhost opt]#
关于数值与字符串的比较
比较符号:==、 != 、<= 、 >=、<、>
cpp
[root@localhost opt]# awk 'NR==5{print}' zz.txt //打印第五行
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@localhost opt]# awk 'NR==5' zz.txt //打印第五行
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@localhost opt]# awk 'NR<5' zz.txt //打印1、2、3、4行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@localhost opt]# awk -F: '$3==0' zz.txt //打印第三列等于0的行
root:x:0:0:root:/root:/bin/bash
[root@localhost opt]# awk -F: '$1=="root"' zz.txt //打印第一列等于root的行
root:x:0:0:root:/root:/bin/bash
[root@localhost opt]# awk -F: '$3>=1000' /etc/passwd //打印第三列大于1000的行
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
cxc:x:1000:1000:cxc:/home/cxc:/bin/bash
[root@localhost opt]# awk -F: '$3<10 || $3>1000' /etc/passwd //打印第三列小于10或者大于100的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
[root@localhost opt]# awk -F: 'NR>4 && NR<7' zz.txt //打印5、6行
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@localhost opt]# seq 200 | awk '$1%7==0 && $1~/7/' //所有能被7整除并且包含数字7的整数数字
7
70
77
147
175
[root@localhost opt]#
其他内置变量的用法FS(输入)、OFS、NR、FNR、RS、ORS
- FS:输入字段的分隔符 默认是空格
- OFS:输出字段的分隔符 默认也是空格
- FNR:读取文件的记录数(行号),从1开始,新的文件重新重1开始计数
- RS:输入行分隔符 默认为换行符
- ORS:输出行分隔符 默认也是为换行符
5.4、awk高级用法
定义引用变量
cpp
[root@localhost opt]#
[root@localhost opt]# a=100
[root@localhost opt]# awk -v b="$a" 'BEGIN{print b}'
#将系统的变量a,在awk里赋值为变量b,然后调用变量b -v 选项将其传递给 awk
100
[root@localhost opt]#
[root@localhost opt]# awk 'BEGIN{print "'$a'"}'
#直接调用的话需要先用双引号再用单引号
100
[root@localhost opt]#
[root@localhost opt]# awk -vc=1 'BEGIN{print c}' //awk直接定义变量并引用
1
[root@localhost opt]#
[root@localhost opt]# df -h | awk 'BEGIN{getline}/root/{print $0}'
#调用函数getline,读取一行数据的时候并不是得到当前行而是当前行的下一行
/dev/mapper/centos-root 26G 5.1G 21G 20% /
[root@localhost opt]#
[root@localhost opt]# seq 10 | awk '{getline;print $0}' //显示偶数行
2
4
6
8
10
[root@localhost opt]#
[root@localhost opt]#
[root@localhost opt]# seq 10 | awk '{print $0;getline}' //显示奇数行
1
3
5
7
9
[root@localhost opt]#
[root@localhost opt]#
[root@localhost opt]#
5.5、awk if语句
awk的if语句也分为单分支、双分支和多分支
[root@localhost opt]# awk -F: '{if($3<10){print $0}}' /etc/passwd
#第三列小于10的打印整行
[root@localhost opt]# awk -F: '{if($3<10){print $3}else{print $1}}' /etc/passwd
#第三列小于10的打印第三列,否则打印第一列
cpp
[root@localhost opt]# awk -F: '{if($3<10){print $0}}' /etc/passwd
//第三列小于10的打印整行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@localhost opt]#
[root@localhost opt]#
[root@localhost opt]#
[root@localhost opt]#
[root@localhost opt]#
[root@localhost opt]# awk -F: '{if($3<10){print $3}else{print $1}}' /etc/passwd
//第三列小于10的打印第三列,否则打印第一列
0
1
2
3
4
5
6
7
8
operator
games
ftp
nobody
systemd-network
dbus
polkitd
abrt
libstoragemgmt
rpc
colord
saslauth
setroubleshoot
rtkit
pulse
qemu
ntp
radvd
chrony
tss
usbmuxd
geoclue
sssd
gdm
rpcuser
nfsnobody
gnome-initial-setup
avahi
postfix
sshd
tcpdump
cxc
[root@localhost opt]#
5.6、BEGIN END 循环
awk还支持for循环、while循环、函数、数组等
①、第一步:运行BEGIN{ commands }语句块中的语句。
BEGIN语句块在awk开始从输入流中读取行之前被运行,这是一个可选的语句块,比方变量初始化、打 印输出表格的表头等语句通常能够写在BEGIN语句块中。
②、第二步:从文件或标准输入(stdin)读取一行。然后运行pattern{ commands }语句块,它逐行扫描文 件,从第一行到最后一行反复这个过程。直到文件所有被读取完成。
pattern语句块中的通用命令是最重要的部分,它也是可选的。假设没有提供pattern语句块,则默认运 行{ print },即打印每个读取到的行。awk读取的每一行都会运行该语句块。
③、第三步:当读至输入流末尾时,运行END{ commands }语句块。
END语句块在awk从输入流中读取全然部的行之后即被运行。比方打印全部行的分析结果这类信息汇总 都是在END语句块中完毕,它也是一个可选语句块。
(这三个部分缺少任何一部分都可以)
cpp
[root@localhost opt]# awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}'
//调用w命令,并用来统计在线用户数
2
[root@localhost opt]# awk 'BEGIN {FS=":"} ;{if($3>=5){print}}' zz.txt
//先处理完BEGIN的内容,再打印文本里面的内容
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost opt]# awk -F ":" '! ($3<10){print} ' zz.txt
//输出第3个字段的值不小于10的行
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost opt]# awk 'BEGIN{x=0};/\/bin\/bash$/ {x++;print x,$0};END {print x}' /etc/passwd
//统计以/ bin/bash结尾的行数
1 root:x:0:0:root:/root:/bin/bash
2 cxc:x:1000:1000:cxc:/home/cxc:/bin/bash
cxc:x:1000:1000:cxc:/home/cxc:/bin/bash
五、总结
grep 和 egrep 文本过滤 (更适合单纯的查找或匹配文本)
sed 流编辑器 实现编辑的(更适合编辑匹配到的文本)
awk 文本报告生成器 实现格式化文本输出(更适合格式化文本,对文本进行较复杂格式处理)