正则表达式与文本处理

目录

一、正则表达式

1、正则表达式定义

1.1正则表达式的概念及作用

1.2、正则表达式的工具

1.3、正则表达式的组成

2、基础正则表达式

3、扩展正则表达式

4、元字符操作

4.1、查找特定字符

4.2、利用中括号"[]"来查找集合字符

[4.3、查找行首"^"与行尾字符""](#4.3、查找行首“^”与行尾字符“”)

4.4、查找任意一个字符"."与重复字符"*"

4.5、查找连续字符范围"{}"

二、、grep语句

1、grep用法

2、grep案例

2.1、统计root字符总行数

2.2、不区分大小写查找the所有的行

[2.3、将没有出现 root 的行取出来](#2.3、将没有出现 root 的行取出来)

2.4、过滤出IP

三、sed命令

1、sed概述

1.1、sed定义

1.2、sed工作原理

2、sed基本用法

3、sed具体操作

3.1、打印输出

[3.1.2、显示范围 行号](#3.1.2、显示范围 行号)

3.1.3、奇偶数表示

3.2、增加内容

3.3、删除

3.4、替换

3.5、插入文件

3.6、同时编辑

3.7、读取完退出

四、awk命令

1、awk定义

2、工作原理

3、工作流程

3.1、运行模式

3.2、执行流程

4、基本语法

4.1、命令格式

5、实验操作

5.1、内建变量

5.2、内置变量

[5.3、BEGIN END 运算](#5.3、BEGIN END 运算)

5.4、awk高级用法

[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 文本报告生成器 实现格式化文本输出(更适合格式化文本,对文本进行较复杂格式处理)

相关推荐
耶啵奶膘1 小时前
uniapp-是否删除
linux·前端·uni-app
_.Switch2 小时前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
2401_850410832 小时前
文件系统和日志管理
linux·运维·服务器
JokerSZ.2 小时前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
XMYX-03 小时前
使用 SSH 蜜罐提升安全性和记录攻击活动
linux·ssh
芯盾时代3 小时前
数字身份发展趋势前瞻:身份韧性与安全
运维·安全·网络安全·密码学·信息与通信
心灵彼岸-诗和远方4 小时前
DevOps业务价值流:架构设计最佳实践
运维·产品经理·devops
一只哒布刘4 小时前
NFS服务器
运维·服务器
苹果醋35 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
二十雨辰5 小时前
[linux]docker基础
linux·运维·docker