04-Shell编程之正则表达式与文本处理器

目录

4.1正则表达式

[4.1.1 Shell 脚本中的正则表达式主要用于以下几种情况:](#4.1.1 Shell 脚本中的正则表达式主要用于以下几种情况:)

[4.2 grep正则表达式](#4.2 grep正则表达式)

4.2.1grep常用选项

[4.2.4 创建测试文件](#4.2.4 创建测试文件)

[4.3 sed简介](#4.3 sed简介)

[4.3.1 sed的工作原理](#4.3.1 sed的工作原理)

[4.3.2 sed常用选项](#4.3.2 sed常用选项)

[4.3.3 测试](#4.3.3 测试)

[4.3.4 删除符合条件的文本](#4.3.4 删除符合条件的文本)

[4.3.5 替换符合条件的文本](#4.3.5 替换符合条件的文本)

[4.3.5 迁移符合条件的文本](#4.3.5 迁移符合条件的文本)

[4.4 文本处理器awk](#4.4 文本处理器awk)

[4.4.1 内置变量](#4.4.1 内置变量)

[4.4.2 特殊字符](#4.4.2 特殊字符)

[4.4.3 操作符](#4.4.3 操作符)

[4.4.4 正则表达式](#4.4.4 正则表达式)

[4.4.5 命令行选项](#4.4.5 命令行选项)

[4.4.6 awk案例](#4.4.6 awk案例)


4.1正则表达式

正则表达式(Regular Expression,简称regex或regexp)是一种强大的文本处理工具,它允许你定义一种模式,这种模式可以帮助你匹配、查找或替换文本中的字符串。

4.1.1 Shell 脚本中的正则表达式主要用于以下几种情况:

  1. 文本搜索 :使用如 grepegrepfgrep 等命令在文件中搜索符合特定模式的文本。
  2. 文本替换 :使用如 sed 命令进行文本替换。
  3. 字符串处理:在Shell脚本中,有时也直接使用正则表达式来处理字符串。

4.2 grep正则表达式

grep是一个强大的文本搜索工具,它使用正则表达式来搜索文本,并把匹配的行打印出来。grep支持两种正则表达式:基本正则表达式(BRE)和扩展正则表达式(ERE)。以下是grep中正则表达式的详细解释,以及一些示例。

4.2.1grep常用选项

  • -a:不要忽略二进制数据。
  • -A:除了显示符合范本样式的那一行之外,并显示该行之后的内容。
  • -b:在显示符合范本样式的那一行之前,并显示该行之前的内容(通常是字节偏移量)。
  • -c:计算符合范本样式的行数。
  • -C 或 -:除了显示符合范本样式的那一行之外,并显示该行之前后的内容。
  • -d:当指定要查找的是目录而非文件时,使用此选项。
  • -e:指定字符串作为查找文件内容的范本样式。
  • -E:将范本样式作为扩展正则表达式来使用。
  • -f:从文件中读取范本样式。
  • -F:将范本样式视为固定字符串的列表,而不是正则表达式。
  • -G:将范本样式视为普通的表示法来使用(默认)。
  • -h:不显示文件名称。
  • -H:显示文件名称(默认)。
  • -i:忽略字符大小写的差别。
  • -l:只列出文件名称,不显示内容。
  • -L:列出不符合范本样式的文件名称。
  • -n:显示行号。
  • -q:不显示任何信息,通常用于脚本中判断是否存在匹配项。
  • -R 或 -r:递归搜索目录。
  • -s:不显示错误信息。
  • -v:反转查找,即显示不符合范本样式的行。
  • -w:只显示全字符合的行。
  • -x:只显示全行符合的行。
  • -o:只输出文件中匹配到的部分。

4.2.4 创建测试文件

bash 复制代码
[root@localhost ~]# cat test.txt

he was short and fat.

he was weating a blue polo shirt with black pants.

The home of Football on BBC Sport online.

the tongue is boneless but it breaks bones.12!

google is the best tools for search keyword.

PI=3.14

a wood cross!

Actions speak louder than words



#woood #

#woooooooood #

AxyzxyzxyzxyzC

I bet this place is really spooky late at night!

Misfortunes never come alone/single.

I shouldn't have lett so tast.

(1)查看包含"the"的行

bash 复制代码
grep -ni 'the' test.txt

(2)利用[ ]查找集合字符

bash 复制代码
grep -n 'sh[io]rt' test.txt

(3)查找字母"oo"前不是字母"w"的内容

bash 复制代码
 grep -n '[^w]oo' test.txt

4.3 sed简介

sed(Stream EDitor)是一个流编辑器,主要用于对输入数据(文件或管道传输的数据)进行基本的文本转换。它可以对文本进行增删改查等操作,常用于自动化脚本中处理文本文件。

4.3.1 sed的工作原理

sed在处理文本时,会将输入数据读取到其内部的缓冲区(称为模式空间),然后在模式空间中对数据进行处理,最后再将处理后的数据输出。sed的工作流程通常包括读取、执行和输出三个阶段。

4.3.2 sed常用选项

  • -n:静默模式,只输出经过sed处理后的内容。
  • -e:直接在命令行上进行sed编辑操作。
  • -f:将sed命令写在一个文件中,并使用-f选项指定该文件。
  • -r:使用扩展正则表达式。
  • -i:直接修改文件内容,而不是输出到终端。

4.3.3 测试

(1)输出所有内容

bash 复制代码
[root@localhost ~]# sed -n 'p' test.txt 

(2)输出第三行

bash 复制代码
[root@localhost ~]# sed -n '3p' test.txt 

(3)输出3~5行

bash 复制代码
[root@localhost ~]# sed -n '3,5p' test.txt 

(4)输出所有奇数行

bash 复制代码
[root@localhost ~]# sed -n 'p;n' test.txt 

(5)输出所有偶数行

bash 复制代码
[root@localhost ~]# sed -n 'n;p' test.txt 

4.3.4 删除符合条件的文本

(1)删除第3行

bash 复制代码
[root@localhost ~]# nl test.txt | sed '3d'	

(2)删除3~5行

bash 复制代码
[root@localhost ~]# nl test.txt |sed '3,5d'

(3)删除包含cross的行

bash 复制代码
[root@localhost ~]# nl test.txt |sed '/cross/d'

(4)删除以点结尾的行

bash 复制代码
[root@localhost ~]# sed '/\.$/d' test.txt 

4.3.5 替换符合条件的文本

(1)将每行的第一个the换成THE

bash 复制代码
[root@localhost ~]# sed 's/the/THE/' test.txt 

(2)将每行中的第2个l换成L

bash 复制代码
[root@localhost ~]# sed 's/l/L/2' test.txt

(3)将文中所有的the换成THE

bash 复制代码
[root@localhost ~]# sed 's/the/THE/g' test.txt 

(4)在包含the的每行的行首插入#

bash 复制代码
[root@localhost ~]# sed '/the/s/^/#/' test.txt 

(5)在每行的行尾插入字符串EOF

bash 复制代码
[root@localhost ~]# sed 's/$/EOF/' test.txt

(6)将第3~5行中的所有the替换成THE

bash 复制代码
[root@localhost ~]# sed '3,5s/the/THE/g' test.txt

(7)将包含the的所有行中的o都替换成O

bash 复制代码
[root@localhost ~]# sed '/the/s/o/O/g' test.txt

4.3.5 迁移符合条件的文本

|----|----------------|
| 选项 | 作用 |
| H | 复制到剪切板 |
| g | 将剪切板中的内容覆盖到指定行 |
| G | 将剪切板中的内容追加到指定行 |
| w | 保存文件 |
| r | 读取指定文件 |
| a | 追加指定内容 |

(1)将包含the的行迁移至文件的末尾

bash 复制代码
[root@localhost ~]# sed '/the/{H;d};$G' test.txt 

(2)将第1~5行的内容转移至第17行后

bash 复制代码
[root@localhost ~]# sed '1,5{H;d};17G' test.txt 

(3)将包含the的行另存为文件out.txt

bash 复制代码
[root@localhost ~]# sed '/the/w out.txt' test.txt 

(4)将文件/etc/hostname的内容添加到包含the的每一行后

bash 复制代码
[root@localhost ~]# sed '/the/r /etc/hostname' test.txt 

(5)在第3行后插入一个新行,内容为#chkconfig:35 82 20

bash 复制代码
[root@localhost ~]# sed '3a#chkconfig:35 82 20' test.txt 

4.4 文本处理器awk

4.4.1 内置变量

  • NF:字段数量变量。当前行被字段分隔符分割后的字段个数。
  • NR:每行的记录号。从1开始计数,并且当处理多个文件时,计数会跨文件递增。
  • FNR:与NR类似,但它是针对当前文件的记录号。当处理多个文件时,每个文件的记录号都是从1开始。
  • FS:输入字段分隔符。默认是空格,但可以在BEGIN块中重新定义。
  • RS:输入记录分隔符。默认是换行符,但也可以重新定义。
  • OFS:输出字段分隔符。默认是空格,用于print命令打印字段时的分隔符。
  • ORS:输出记录分隔符。默认是换行符,用于print命令打印记录时的分隔符。
  • FILENAME:当前awk正在处理的文件名。

4.4.2 特殊字符

  • \t:制表符。
  • \n:换行符。

4.4.3 操作符

  • ~:匹配。用于正则表达式匹配。
  • !~:不匹配。用于正则表达式不匹配。
  • ==:等于。精确比较两个值。
  • !=:不等于。精确比较两个值。
  • &&:逻辑与。
  • ||:逻辑或。

4.4.4 正则表达式

  • +:在正则表达式中,表示匹配前面的元素一个或多个。
  • /[0-9][0-9]+/:匹配一个数字后跟一个或多个数字。
  • /[0-9][0-9]*/:匹配一个数字后跟零个或多个数字(包括一个数字后跟零个数字的情况)。

4.4.5 命令行选项

  • -F'[:#/]':定义输入字段分隔符为冒号(:)、井号(#)或斜杠(/)。这意味着awk将使用这三个字符中的任意一个来分割字段。

4.4.6 awk案例

(1)按字段输出文本

bash 复制代码
awk -F":" '{print $3}' /etc/passwd		//显示第三列
awk -F":" '{print $1 $3}' /etc/passwd                       //$1与$3相连输出,无空格,
awk -F":" '{print $1,$3}' /etc/passwd                       //多了一个逗号,输出第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		##显示第七个字段为/bash的行的第一个字段
awk -F: 'NR==5{print}' /etc/passwd                         //显示第5行
awk -F":" '{print $1 " " $3}' /etc/passwd                  //$1与$3之间手动添加空格分隔

(2)通过管道、双引号调用shell命令

bash 复制代码
awk -F: '/bash$/{print | "wc -l"}' /etc/passwd     ##统计bash用户的个数
awk 'BEGIN {while ("w" | getline) n++ ; {print n-2}}'   ##统计在线用户的数量
awk 'BEGIN {"hostname" | getline;print $0}'      ##输出当前主机名


awk -F: '$1~/mail/ && $3>6 {print }' /etc/passwd         //逻辑与,$1匹配mail,并且$3>6
awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd  
awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd       //逻辑或,统计以mail开头或第3列大于1000的行
awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd 
相关推荐
薛·几秒前
记一次因ThreadPoolExecutor多线程导致服务器内存压满问题
java·服务器
水彩橘子6 分钟前
shellhub 部署
运维
结衣结衣.13 分钟前
完全理解C语言函数
java·linux·c语言·数据库·经验分享·笔记
零K沁雪14 分钟前
VirtualBox 安装 Ubuntu Server24.04
linux·运维·ubuntu
Hundreds_N20 分钟前
kali改回官方源后更新失败
linux·kali
FlowingRiver22 分钟前
nginx配置stream代理
运维·nginx
星殇曦落24 分钟前
nginx的重定向(rewrite)
运维·nginx
wenhui.wang44 分钟前
Linux/Ubuntu访问局域网共享文件夹
linux·ubuntu
q567315231 小时前
Python/Django 服务器升级脚本
服务器·开发语言·python·游戏·django
光亮§那方1 小时前
linux - cp 命令
linux·ubuntu