11-正则表达式

蒸汽
蒸汽
发布于 2024-12-28 / 11 阅读
0
0

11-正则表达式

一、正则表达式:

(Regular Expression, RE):是通过一些特殊字符的排列,用”搜寻/取代/删除“ 一列或多列文字字串

分级:正则表达式的字串表示方式依照不同的严谨度分为:基础正则表达式与延伸正则表达式

ps:延伸正则表达式除了可以处理一组字串外还可以处理群组字串

ps:==正则表达式和万用字符完全不同==!万用字符是bash操作接口的一个功能。正则表达式是字串处理方式

1.基础正则表达式

前提:首先要确定正则表达式使用的语系!!!(否则结果不一定正确)

例如: image.png

image.png

grep的进阶选项 image.png

grep练习:

  1. 想要查找test 或者taste两个单字的行

grep -n 't[ae]st' xxx.txt
#[]中不论有几个字符,他都仅代表一个字符而已

2.想要找oo,但不想要前面有g

grep -n '[^g]oo' xxx.txt
#[^]反向选择内部的一个字符

3.想要找oo,但不想要前面有小写字符

grep -n '[^a-z]oo' xxx.txt
grep -n '[^[:lower:]]oo' xxx.txt
#符号可以配合使用

4.想要找有the的,但只出现行^首(尾$)

grep -n '^the' xxx.txt
#只出现在行首

ps:^在[]内外的表达是不同的!在内为反向选择,在外为行首的意思

5.找出空白行

grep -n '^$' xxx.txt
#找出空白行
​
grep -v '^$' xxx
#找出非空白的行,节省打印空间,实用

6.*与.

image.png ps:==*代表的是重复0个或者多个前面的RE字符==

7.得到g......g

grep -n 'g.*g' xxx.txt
#秒! 表示中间有0个或者多个的.!!!

8.{}符

#找到g....g中间有2-5个o的
grep -n 'o\{2,5\}' xxx.txt
​
#找到中间有2个以上的o
grep -n 'go*g' xxx.txt
grep -n 'go\{2,\}' xxx.txt

总结:

image.png image.png

二、sed工具

sed是一个管线命令,可以分析stdin。而且sed还可以将数据进行取代、删除、新增、颉取特定行的功能

image.png

练习: 1.列出内容并打印行号,同时删除2-5行

nl /etc/passwd | sed '2,5d'

2.承上题,在第二行后(亦即是加在第三行)加上“drink tea?”字样

nl /etc/passwd | sed '2a drink tea'
​
#如果要在第二行加入,则把a改成i

3.承上题,如何新增多行?

#使用/符号,进行加入多行操作
nl /etc/passwd | sed '2a drink tea .....\
drink tea?'

输出: image.png

4.承上题,取代2-5行内容

nl /etc/passwd | sed '2,5c No 2-5 number'

5.承上题,仅列出文件内的5-7行

nl /etc/passwd | sed -n '5,7p'
#p:print

6.搜索与取代

sed 's/要被取代的字串/新的字串/g'

image.png

sed与正则表达式混合练习

7.删除man中的前面注解,只保留有用的行 image.png image.png

sed直接修改文件内容(危险动作) image.png

三、延伸正则表达式

延伸正则表达式可以通过群组功能“|”来进行一次搜寻!那个在单引号内的管线意义为“or“

#例如我们去除空白行和行首为#的行列,之前要使用两次管线
grep -v '^$' xxx.txt | grep -v '^#'
​
#现在可以使用延伸正则表达式
egrep -v '^$|^#' xxx.txt
#egrep == grep -E

image.png https://img-1329949402.cos.ap-shanghai.myqcloud.com/20241226065840.png

ps:==!在延伸表达式里不是特殊字符!!! 常见错误:[!a-z]是反向选择? 不对,要‘a-z’==

11.4 文件的格式化与相关处理

11.4.1 格式化打印

printf

printf '打印格式' 实际内容
​
printf '%s\t %s\t %s\t %s\t %s\t \n' $ (cat printf.txt)
# %s表示不固定长度字串
# 每组数据中有一个[tab]
​
printf '%10s %5i %5i %5i %8.2f' $ (cat printf.txt | grep -v Name)
#%8.2f 意思是总长占8个字符,小数点后共两位

11.4.2 awk

awk: awk是一个优秀的数据处理工具

相比sed一次处理一行,awk倾向于一次处理一行中的一个字段

awk '条件类型1{动作1} 条件类型2{动作2}...' filename
​
#例如
last -n 5 | awk '{print $1 "\t" $3}'
​
#$n代表第n栏数据。如果是$0代表一整列数据
​
#原格式
dmtsai pts/0 192.168.1.100 Tue Jui 14 17:32  still  loggedin
dmtsai pts/0 192.168.1.100 Tue Jui 14 17:32  still  loggedin
dmtsai pts/0 192.168.1.100 Tue Jui 14 17:32  still  loggedin
dmtsai pts/0 192.168.1.100 Tue Jui 14 17:32  still  loggedin
dmtsai pts/0 192.168.1.100 Tue Jui 14 17:32  still  loggedin
​
#输出如下
dmtsai  192.168.1.100
dmtsai  192.168.1.100
dmtsai  192.168.1.100
dmtsai  192.168.1.100
dmtsai  192.168.1.100

整个awk的处理流程如下:

  • 读入第一行,并将第一行的数据填入$0, $1...等变量当中

  • 依据条件类型的限制,判断是否需要进行后面的”动作“

  • 做完所有的动作与条件类型

  • 若还有后续的”行“的数据,则重复上面的1-3 的步骤,直到所有的数据都读完为止

awk内置变量

  • NF: 每一行($0)拥有的字段总数

  • NR: 目前awk处理的是”第几行“数据

  • FS: 目前的分割字符,默认是空白键

#示例
last -n 5 | awk'{print $1 "\t" lines: "NR", columns: "NF"}'
​
#输出结果
dmtsai lines:1   columns:10
dmtsai lines:1   columns:10
dmtsai lines:1   columns:10
dmtsai lines:1   columns:10
dmtsai lines:1   columns:9

awk的逻辑运算字符

运算单元

代表意义

>

大于

<

小于

>=

大于等于

<=

小于等于

==

等于

!=

不等于

cat /etc/passwd | awk 'BEGIN {FS = ":"} $3 < 10 {print $1 "\t" $3}'
​
#输出
root   0
bin    1
daemon 2
...
​

awk实现计算

#示例数据如下,假如有一个薪资表为pay.txt
​
Name    1st    2nd    3th
VBird   23000  24000  25000
DMTsai  21000  20000  23000
Bird2   43000  42000  41000
​
#计算每个人的总额并且格式化输出
cat pay.txt | \
> awk 'NR == 1 {printf "%10s %10s %10s %10s %10s\n", $1,$2,$3,$4,"Total"}'
> NR>=2 {total = $2 + $3 + $4
> printf "%10s %10d %10d %10d %10.2f\n", $1,$2,$3,$4, total}
​

11.4.3 文件比对工具

比对ASCII纯文本工具:diff 比对非存文本工具: cmp

diff:主要以行为比对单位

diff [-bBi] from-file to-file
-b: 忽略一行当中,仅有的多个空白的差异
-B: 忽略空白行的差异
-i: 忽略大小写的不同

cmp:主要以字节为比对单位

cmp可以用来比对binary file

cmp [-l] file1 file2
-l:将所有的不通电的字节处都列出来。因为cmp默认金辉输出第一个发现的不同点

Patch

diff ➡ 找到差异 ➡ 写入patch文件 ➡ 用patch文件实现更新与回退

#制作,patch文件
diff -Naur passwd.old passwd.new > passwd.patch cat passwd.patch
​
#patch文件内容
--- passwd.old 2015-07-14 22:37:43.322535054 +0800 <==旧文件的ؑ信息 
+++ passwd.new 2015-07-14 22:38:03.010535054 +0800 <==新文件的信息
@@ -1,9 +1,8 @@ <==新旧文件要修改数据的界定范围,
旧文件൘ 1-9 行,
新文件൘ 1-8 行 
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 <==左侧文件删䲔 
+no six line <==右侧新文件加
​
#使用patch文件
patch -p0 < passwd.patch
​
patch -p0 < passwd.patch #更新旧版数据
patching file passwd.old
​
patch -R -p0 < passwd.patch # 恢复旧文件的内容

11.4.4文件打印 pr

image.png


评论