Linux正则表达式基础

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Jesse_Mx/article/details/80076849

正则表达式

简单而言,正则表达式通过一些特殊符号的帮助,使用户可以轻松快捷的完成查找、删除、替换等处理程序。

正则表达式特殊符号

一些特殊符号的表示

[:alnum:]代表英文大小写字母及数字 
[:alpha:]代表英文大小写字母
[:blank:]代表空格和 tab 键
[:cntrl:]键盘上的控制按键,如 CR,LF,TAB,DEL
[:digit:]代表数字
[:graph:]代表空白字符以外的其他
[:lower:]小写字母
[:print:]可以被打印出来的任何字符
[:punct:]代表标点符号
[:upper:]代表大写字符
[:space:]任何会产生空白的字符如空格,tab,CR 等
[:xdigit:]代表16进制的数字类型

grep查找

grep命令可以使用正则表达式搜索文本,并把匹配的行打印出来,其常用方法如下:

 grep [-acinv] [--color=auto] '搜寻字符串' filename
选项与参数:
-a :将 binary 文件以 text 文件的方式搜寻数据
-c :计算找到 '搜寻字符串' 的次数
-i :忽略大小写的不同,所以大小写视为相同
-n :顺便输出行号
-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
--color=auto :可以将找到的关键词部分加上颜色的显示

case1

查找特定的字符串

grep -n 'the' regular_express.txt # 查找'the' 字符串

case2

字符组匹配,[]中包含的任意一个字符,只能是一个,字符组支持”-“连字符来表示一个范围,[^ ...] 是排除型字符组,用来排除后面的字符

[abc]           :表示“a”或“b”或“c”
[0-9]           :表示 0~9 中任意一个数字,等价于[0123456789]
[\u4e00-\u9fa5] :表示任意一个汉字
[^a1<]          :表示除“a”、“1”、“<”外的其它任意一个字符
[^a-z]          :表示除小写字母外的任意一个字符

grep -n 't[ae]st' regular_express.txt # 查找“tast”或者“test”两个字符串
grep -n '[^#]' regular_express.txt #查找不包含“#”的字符串
grep -n '[^g]oog' regular_express.txt # 查找"oog",但是不查找"goog"
grep -n '[^go]oog'regular_express.txt# 查找"oog",但是不查找"goog"和"ooog"
grep -n '[[:lower:]]' regular_express.txt # 查找小写字母

case3

行首符^,行尾符$,具体应用如下

grep -n '^the' regular_express.txt # 查找行首为"the"的所有行
grep -n '^[A-Z]' regular_express.txt # 查找行首为大写字母的所有行
grep -n '[^A-Z]' regular_express.txt # 查找除了大写字母以外的所有字符,注意和上面区分
grep -n 'd$' regular_express.txt # 查找以"d"结尾的所有行
grep -n '^$' regular_express.txt # 查找空行

case4

grep的反向选择和管道线联合应用

grep -v '^$' /etc/insserv.conf | grep -v '^#' # 先过滤掉空白行,然后过滤掉注释行(以#开头)

case5

小数点”.”表示任意一个字符,星号”*”表示重复的字符

grep -n 'a.ou.' regular_express.txt # 查找a?ou?类型的字符

*(星号):代表重复前面0个或者多个字符。
e*: 表示具有空字符或者一个以上e字符。
ee*,表示前面的第一个e字符必须存在。第二个e则可以是0个或者多个e字符。
eee*,表示前面两个e字符必须存在。第三个e则可以是0个或者多个e字符。
ee*e :表示前面的第一个与第三个e字符必须存在。第二个e则可以是0个或者多个e字符。

case6

大括号{}可以限定一个范围区间重复的字符数,注意,必须用转义字符来表示这个大括号,即为\{\} ,否则出错。

grep -n 'o\{2\}' regular_express.txt # 查找连续的两个"o"
grep -n 'go\{2,5\}g' regular_express.txt # 查找g后面接2到5个o,然后再接g的字符串

小结

^word    表示带搜寻的字符串(word)在行首
word$    表示带搜寻的字符串(word)在行尾
.(小数点) 表示1个任意字符
\        表示转义字符,在特殊字符前加\会将特殊字符意义去除
*        表示重复0到无穷多个前一个RE(正则表达式)字符
[list]   表示搜索含有l,i,s,t任意字符的字符串
[n1-n2]  表示搜索指定的字符串范围,例如[0-9] [a-z] [A-Z][^list]  表示反向字符串的范围,例如[^0-9]表示非数字字符,[^A-Z]表示非大写字符范围
\{n,m\}  表示找出n到m个前一个RE字符
\{n,\}   表示n个以上的前一个RE字符

sed编辑器

sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。sed 编辑器逐行处理文件(或输入),并将结果发送到屏幕。其常用方法如下:

sed [-nefri] ‘command’ 输入文本    

常用选项:
-n:使用安静(silent)模式。如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e:直接在指令列模式上进行 sed 的动作编辑;
-f:直接将 sed 的动作写在一个档案内,-f filename则可以执行 filename 内的sed 动作;
-r:sed的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i:直接修改读取的档案内容,而不是由屏幕输出。       

常用命令:
a:新增,a的后面可以接字串,而这些字串会在当前行的下一行
c:取代,c的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d:删除,因为是删除,所以d后面通常不接任何内容
i:插入,i的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行)
p:打印,将某个选择的部分打印出。通常p会与参数sed -n一起运作(仅打印需要的行)
s:替换,可以直接进行替换的工作,通常s动作可以搭配正规表示法

case1

nl regular_express.txt | sed '2,5d' # 将 regular_express.txt 的内容列出并打印行号,同时,将2-5 行删除显示
nl regular_express.txt | sed '2d' # 同上,仅删除第二行
nl regular_express.txt | sed '3,$d' #同上,删除第3行到最后一行
sed -i '1d' regular_express.txt # 在原文件中删除第 1 行

case2

a表示在行后加上字符串,i表示在行前添加字符串

nl regular_express.txt | sed '2a test' # 在第二行后添加 test 字符串
nl regular_express.txt | sed '2i test' # 在第二行前添加 test 字符串
nl regular_express.txt | sed '2a  test\ntest' # 在第二行后加入两行 test,“\n”表示换行符

case3

c 为替换内容选项

nl regular_express.txt | sed '2,5c No 2-5 number' # 2-5 行内容取代为"No 2-5 number" 

case4

sed ‘s/被替换字符串/新字符串/g’

/sbin/ifconfig eth0 |grep 'inet ' # 在/sbin/ifconfig eth0 的结果中查找‘inet’,打印至终端
# 结果是inet addr:192.168.40.12  Bcast:0.0.0.0  Mask:255.255.255.0

/sbin/ifconfig eth0 |grep 'inet '| sed 's/inet ....://g' # 将IP地址前的字符去掉
/sbin/ifconfig eth0 |grep 'inet '| sed 's/.\{0,9\}://' # 功能和前面一样,去掉:前的若干个字符,最多9个

/sbin/ifconfig eth0 |grep 'inet '| sed 's/.inet...://g'| sed 's/.....:.*$//g' # 将IP地址后的部分也去掉,.*表示无限个任意字符

awk文本分析

awk是一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

使用方法

awk '{pattern + action}' {filenames}

其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号{}不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用两个斜杠/括起来。

case1

last -n 5 # 取出登录数据前5行
# 结果如下
root     pts/1   192.168.1.100  Tue Feb 10 11:21   still logged in
root     pts/1   192.168.1.100  Tue Feb 10 00:46 - 02:28  (01:41)
root     pts/1   192.168.1.100  Mon Feb  9 11:41 - 18:30  (06:48)
dmtsai   pts/1   192.168.1.100  Mon Feb  9 11:41 - 11:41  (00:00)
root     tty1                   Fri Sep  5 14:09 - 14:10  (00:01)

last -n 5 | awk  '{print $1}' # 显示最近登录的5个帐号,$1代表用空格或TAB隔开的第一个字段,以此类推,此句表示取每一行的第一个字段
# 结果如下
root
root
root
dmtsai
root

case2

cat /etc/passwd |awk  -F ':'  '{print $1}' # 功能类似,使用了-F ':'指定分隔符为冒号
# 结果如下
root
daemon
bin
sys

cat /etc/passwd |awk  -F ':'  '{print $1"\t"$7}' # 显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割
# 结果如下
root    /bin/bash
daemon  /bin/sh
bin     /bin/sh
sys     /bin/sh

case3

awk -F: '/root/' /etc/passwd # 搜索/etc/passwd有root关键字的所有行
# 结果如下
root:x:0:0:root:/root:/bin/bash

这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。

搜索支持正则,例如找root开头的: awk -F: ‘/^root/’ /etc/passwd

awk -F: '/root/{print $7}' /etc/passwd # 搜索/etc/passwd有root关键字的所有行,并显示对应的shell
# 结果如下
/bin/bash

这里指定了action{print $7}

awk内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

ARGC               命令行参数个数
ARGV               命令行参数排列
ENVIRON            支持队列中系统环境变量的使用
FILENAME           awk浏览的文件名
FNR                浏览文件的记录数
FS                 设置输入域分隔符,等价于命令行 -F选项
NF                 浏览记录的域的个数(每一行字段个数)
NR                 已读的记录数(行号)
OFS                输出域分隔符
ORS                输出记录分隔符
RS                 控制记录分隔符

举一个例子

# 统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容($0是代指整行)
awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

扩展规则

egrep

正规表达方法

grep -v '^$' regular_express.txt |grep -v '^#' # 先去除空行,再去除注释行

需要用到管道线,grep搜寻了两次,如果使用延伸型的正则表达式,则可以简化为

egrep -v '^$|^#' regular_express.txt # 相当于或操作

grep 默认仅支持基础正则表达式,如果要使用扩展性正则表达式,可以使用 grep - E。grep -E 与 egrep 相当于命令别名关系。

常用扩展规则

加号+表示重复一个或一个以上的前一个 RE 字符

egrep -n 'go+d' regular_express.txt # gd之间,o至少重复两次
grep -n 'goo*d' regular_express.txt # 普通写法

问号?表示重复重复**零个或一个前一个**RE字符

egrep -n 'go?d' regular_express.txt # 仅搜索good或god

分隔符|表示用或的方式找出数个字符串

egrep -n 'gd|good' regular_express.txt

括号()表示找出群组字符串

egrep -n 'g(la|oo)d' regular_express.txt # 搜索good或glad

括号加号{}+表示多个重复群组判别

# 找开头是A结尾是C,中间有一个以上的 ‘xyz’ 或 ‘xz’ 字符串
echo 'AxyzxyzxyzxyzC'|egrep 'A(xyz)+C' # 可以匹配
echo 'AxyzxyzxyzxyzC'|egrep 'A(xz)+C' # 无法匹配

猜你喜欢

转载自blog.csdn.net/Jesse_Mx/article/details/80076849