Shell 编程之正则表达式与编程三剑客(awk,sed,grep)

文章目录

  • 一、正则表达式
    • 1.1、正则表达式的定义
    • 1.2、基础正则表达式
    • 1.3、扩展正则表达式
  • 二、文本处理器
    • 2.1、grep
      • 2.1.1、grep 常用用法示例
    • 2.2、sed
      • 2.2.1、sed 工具概述
      • 2.2.2、sed 命令格式
      • 2.2.3、sed 常见命令选项
      • 2.2.4、sed 常用用法示例
    • 2.3、awk
      • 2.3.1、awk 常见用法
      • 2.3.2、awk 工作原理
      • 2.3.3、awk 命令格式
      • 2.3.4、 awk 常用用法示例

一、正则表达式

1.1、正则表达式的定义

  1. 正则表达式又称正规表达式、常规表达式。在代码中常简写为 regex、regexp 或 RE。正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,简单来说, 是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。
  2. 正则表达式是由普通字符与元字符组成的文字模式。模式用于描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。其中普通字符包括大小写字母、数字、标点符号及一些其他符号,元字符则是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
  3. 正则表达式一般用于脚本编程与文本编辑器中。很多文本处理器与程序设计语言均支持正则表达式,如Linux 系统中常见的文本处理器(grep、egrep、sed、awk)。正则表达式具备很强大的文本匹配功能,能够在文本海洋中快速高效地处理文本。

1.2、基础正则表达式

正则表达式的字符串表达方法根据不同的严谨程度与功能分为基本正则表达式与扩展正则表达式。基础正则表达式是常用正则表达式最基础的部分。在 Linux 系统中常见的文件处理工具中 grep 与 sed 支持基础正则表达式,而 egrep 与 awk 支持扩展正则表达式。
Shell 编程之正则表达式与编程三剑客(awk,sed,grep)_第1张图片

1.3、扩展正则表达式

常见元字符

常见元字符 作用
+ 重复一个或者一个以上的前一个字符
零个或者一个的前一个字符
l 使用或者(or)的方式找出多个字符
() 查找“组”字符串
()+ 辨别多个重复的组

示例

+:执行“egrep -n ‘wo+d’ test.txt”命令,即可查询"wood" “woood” "woooooood"等字符串

?:执行“egrep -n ‘bes?t’ test.txt”命令,即可查询“bet”“best”这两个字符串

| :执行“egrep -n ‘of|is|on’ test.txt“ 命令即可查询"of"或者"if"或者"on"字符串

() :“egrep -n ‘t(a|e)st’ test.txt”。“tast”与“test”因为这两个单词的“t”与“st”是重复的,所以将“a”与“e”列于“()”符号当中,并以“|”分隔,即可查询"tast"或者"test"字符串

()+:“egrep -n ‘A(xyz)+C’ test.txt”。该命令是查询开头的"A"结尾是"C",中间有一个以上的 "xyz"字符串的意思

二、文本处理器

在 Linux/UNIX 系统中包含很多种文本处理器或文本编辑器,其中包括我们之前学习过的VIM 编辑器与 grep 等,而 grep,sed,awk 更是 shell 编程中经常用到的文本处理工具,被称之为 Shell 编程三剑客。

2.1、grep

-n :显示行号

-i :不区分大小写

-v :反向过滤

-o :精确匹配字符

2.1.1、grep 常用用法示例

示例:都以 /etc/passwd下为例子
查找出特定字符“the” 所在位置

[root@localhost ~]# grep -n 'the' /etc/passwd
29:tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin

查找出特定字符“the” 所在位置,不区分大小写

[root@localhost ~]# grep -in 'the' /etc/passwd
29:tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin

反向选择,如查找不包含“the”字符的行

[root@localhost ~]# grep -vn 'the' /etc/passwd
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
。。。省略部分内容

同时查找到“shirt”与“short”这两个字符串

[root@localhost ~]# grep -n 'sh[io]rt' /etc/passwd

查找包含重复单个字符“oo”

[root@localhost ~]# grep -n 'oo' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:operator:x:11:0:operator:/root:/sbin/nologin
22:setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
38:postfix:x:89:89::/var/spool/postfix:/sbin/nologin

查找“oo” 前面不是“r”的字符串

[root@localhost ~]# grep -n '[^r]oo' /etc/passwd
5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
22:setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
38:postfix:x:89:89::/var/spool/postfix:/sbin/nologin

检索“oo”前面不存在大小写字母的字符串

[root@localhost ~]# grep -n '[^a-zA-Z]oo' /etc/passwd
[root@localhost ~]# 

查找包含数字的行

[root@localhost ~]# grep -n '[0-9]' /etc/passwd
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
。。。省略部分内容

查询以 w 开头 d 结尾,中间的字符可有可无的字符串

[root@localhost ~]# grep –n'w.*d' /etc/passwd
[root@localhost ~]# 

查询以 w 开头 d 结尾,中间包含至少一个 o 的字符串

[root@localhost ~]#  grep –n'woo*d' /etc/passwd
[root@localhost ~]# 

oo*”, 则第一个 o 必须存在,第二个 o 则是零个或多个 o,所以凡是包含 o、oo、ooo、ooo,等的资料都符合标准

[root@localhost ~]# grep –n'oo*' /etc/passwd
[root@localhost ~]# 

2.2、sed

2.2.1、sed 工具概述

文本处理工具,读取文本内容,根据指定的条件进行处理,如删除、替换、添加等
可在无交互的情况下实现相当复杂的文本处理操作
被广泛应用于Shell脚本,以完成自动化处理任务

工作原理
读取——执行——显示

2.2.2、sed 命令格式

sed[选项] ‘操作’ 参数
sed [选项] -f scriptfile 参数

其中,“参数”是指操作的目标文件,当存在多个操作对象时用,文件之间用逗号“,”分隔;
而 scriptfile 表示脚本文件,需要用“-f”选项指定,当脚本文件出现在目标文件之前时,表示通过指定的脚本文件来处理输入的目标文件

2.2.3、sed 常见命令选项

-e 或–expression= :表示用指定命令或者脚本来处理输入的文本文件。
执行两条命令时添加,执行一条时一般忽略
-f 或–file= : 表示用指定的脚本文件来处理输入的文本文件。
-h 或–help : 显示帮助。
-n、–quiet 或 silent:表示仅显示处理后的结果。
-i : 直接编辑文本文件。

2.2.4、sed 常用用法示例

a : 增加,在当前行的下面增加一行指定内容
c : 替换 ,将指定的“行”替换为指定内容
d : 删除,删除选定的行
i : 插入,在选定行上面插入一行指定内容
p : 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出,其通常与“ -n ” 选项一起使用
s : 替换,替换指定字符
y: 字符转换,用y替换时,新字符与旧字符长度一定要相同
=: 打印行号
l: 打印数据流中的文本和不可打印的AscII码,比如结束符 $ 制表符 \t

sed -n ‘p’ 123.txt ##输出##
sed -n ‘p;n’ 123.txt ##输出奇数行##
sed -n ‘n;p’ 123.txt ##输出偶数行##
sed -n ‘3p’ 123.txt ##输出第3行##
sed -n ‘3,5p’ 123.txt ##输出第3-5行##
sed -n ‘1,5{p;n}’ 123.txt ##输出第1-5行的奇数行##
sed -n ‘10,$ {n;p}’ 123.txt ##输出第10行至文件尾的偶数行##
sed -n ‘/the/p’ 123.txt ##输出包含the的奇数行##
sed -n ‘4,/the/p’ 123.txt ##输出从第4行至第一个包含the的行##
sed -n ‘/the/=’ 123.txt ##输出包含the的行所在的行号,等于(=)用来输出行号##
sed -n ‘/[0-9]$/p’ 123.txt ##输出以数字结尾的行##
sed -n ‘/^PI/p’ 123.txt ##输出以PI开头的行##
sed -n ‘/<wood>/p’ 123.txt ##输出包含单词wood的行,<、>代表单词边界##

2.3、awk

2.3.1、awk 常见用法

前面提到 sed 命令常用于一整行的处理,而 awk 比较倾向于将一行分成多个“字段”然后再进行处理,且默认情况下字段的分隔符为空格或 tab 键。awk 执行结果可以通过 print 的功能将字段数据打印显示。在使用 awk 命令的过程中,可以使用逻辑操作符“&&”表示“与”、“||” 表示“或”、“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。

2.3.2、awk 工作原理

awk 借用 shell 中类似于位置变量的方法, 用$1、$2、$3…顺序地表示行(记录)中的不同字段。另外 awk 用$0 表示整个行(记录)。不同的字段之间是通过指定的字符分隔。awk 默认的分隔符是空格。awk 允许在命令行中用“-F 分隔符”的形式来指定分隔符。
Shell 编程之正则表达式与编程三剑客(awk,sed,grep)_第2张图片

2.3.3、awk 命令格式

awk 选项 ‘模式或条件 {编辑指令}’ 文件 1 文件 2 … 过滤并输出文件中符合条件的内容

awk -f 脚本文件 文件 1 文件 2 … 从脚本中调用编辑指令,过滤并输出内容

awk 包含几个特殊的内建变量(可直接用)如下所示:

FS: 指定每行文本的字段分隔符,默认为空格或制表位。

NF: 当前处理的行的字段个数。

NR: 当前处理的行的行号(序数)。

$0: 当前处理的行的整行内容。

$n: 当前处理行的第 n 个字段(第 n 列)。

FILENAME:被处理的文件名。

RS: “行“分割符,awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录
wak一次仅读入一条记录,以进行处理,预设值是” \n “

2.3.4、 awk 常用用法示例

按行输出文本

awk{print}’ test.txt 
##输出所有内容,等同于 cat test.txt
awk 'NR==1,NR==3{print}' test.txt
##输出第1~3行内容
awk ‘BEGIN{RS=""};END{print NR}’ /etc/squid/squid.conf
##统计以空行分隔的文本段落数
awk '/^root/{print}' /etc/passwd
##输出以root开头的行
awk 'NR==1,NR==3{print}' test.txt
##输出第1~3行内容
awk '(NR%2)==1{print}' test.txt
##输出所有奇数行内容
awk '/nologin$/{print}' /etc/passwd
##输出以 nologin 结尾的行
awk 'BEGIN {x=0} ; /\/bin\/bash$/{x++};END {print x}' /etc/passwd
##统计以/bin/bash 结尾的行数,等同于 grep -c "/bin/bash$" /etc/passwd
awk 'BEGIN{RS=""};END{print NR}' /etc/squid/squid.conf
##统计以空行分隔的文本段落数

按字段输出文本

awk{print $3}’ test.txt 
##输出每行中(以空格或制表位分隔)的第 3 个字段
awk{print $1,$3}’ test.txt 
##输出每行中的第 1、3 个字段
awk -F “:” ‘$2==""{print}’ /etc/shadow 
##输出密码为空的用户的shadow 记录
awk ‘BEGIN {FS=":"}; $2==""{print}’ /etc/shadow
##输出密码为空的用户的shadow 记录
awk -F “:” ‘$7~"/bash"{print $1}’ /etc/passwd
##输出以冒号分隔且第 7 个字段中包含/bash 的行的第 1 个字段
awk($1~“nfs”)&&(NF==8){print $1,$2}’ /etc/services
##输出包含 8 个字段且第 1 个字段中包含 nfs 的行的第 1、2 个字段
awk -F: '/bash 7!="/sbin/nologin")print′/etc/passwd
##输出第7个字段既不为/bin/bash也不为/sbin/nologin的所有行■通过管道、双引号调用Shell命令
awk −F:′/bash/{print | “wc -l”}’ /etc/passwd
##调用wc -l 命令统计使用 bash 的用户个数,等同于 grep -c “bash$” /etc/passwd
awk ‘BEGIN {while (“w” | getline) n++ ; {print n-2}}##调用w 命令,并用来统计在线用户数
awk ‘BEGIN { “hostname” | getline ; print $0}##调用hostname,并输出当前的主机名

你可能感兴趣的:(理论,实验,shell,shell)