linux正则表达式测试器,Shell学习篇:正则表达式和文本处理工具

原标题:Shell学习篇:正则表达式和文本处理工具

一 什么是正则

正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。

生活中处处都是正则:

比如我们描述:4条腿

你可能会想到的是四条腿的动物或者桌子,椅子等

继续描述:4条腿,活的

就只剩下四条腿的动物这一类了

在linux中,通配符是由shell解释的,而正则表达式则是由命令解释的,下面我们就为大家介绍三种文本处理工具/命令:grep、sed、awk,它们三者均可以解释正则。

二 grep

参数

-n :显示行号

-o :只显示匹配的内容

-q :静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容

-l :如果匹配成功,则只将文件名打印出来,失败则不打印,通常-rl一起用,grep -rl 'root' /etc

-A :如果匹配成功,则将匹配行及其后n行一起打印出来

-B :如果匹配成功,则将匹配行及其前n行一起打印出来

-C :如果匹配成功,则将匹配行及其前后n行一起打印出来

--color

-c :如果匹配成功,则将匹配到的行数打印出来

-E :等于egrep,扩展

-i :忽略大小写

-v :取反,不匹配

-w:匹配单词

[root@MiWiFi-R3-srv ~]# cat a.txt

root123

ROot asdf

Root_123

rOOtss

root 123

[root@MiWiFi-R3-srv ~]# grep -i "root" a.txt

root123

ROot asdf

Root_123

rOOtss

root 123

[root@MiWiFi-R3-srv ~]# grep -w "root" a.txt

root 123

grep种类

grep

fgrep

pgrep

egrep

正则介绍

^行首

$行尾

.除了换行符以外的任意单个字符

*前导字符的零个或多个

.*所有字符

[]字符组内的任一字符

[^]对字符组内的每个字符取反(不匹配字符组内的每个字符)

^[^]非字符组内的字符开头的行

[a-z] 小写字母

[A-Z] 大写字母

[a-Z] 小写和大写字母

[0-9] 数字

>单词尾

扩展正则 sed 加 -r 参数 或转义

grep 加 -E 或 egrep 或转义

AWK 直接支持 但不包含{n,m}

可以使用--posix支持

[root@MiWiFi-R3-srv ~]# awk '/ro{1,3}/{print}' /etc/passwd

[root@MiWiFi-R3-srv ~]# awk --posix '/ro{1,3}/{print}' /etc/passwd

sed -n '/roo?/p' /etc/passwd

sed -rn '/roo?/p' /etc/passwd

? 前导字符零个或一个

+ 前导字符一个或多个

abc|def abc或def

a(bc|de)f abcf 或 adef

x{m} x出现m次

x{m,} x出现m次至多次(至少m次)

x{m,n} x出现m次至n次

posix定义的字符分类

[:alnum:] Alphanumeric characters.

匹配范围为 [a-zA-Z0-9]

[:alpha:] Alphabetic characters.

匹配范围为 [a-zA-Z]

[:blank:] Space or tab characters.

匹配范围为 空格和TAB键

[:cntrl:] Control characters.

匹配控制键 例如 ^M 要按 ctrl+v 再按回车 才能输出

[:digit:] Numeric characters.

匹配所有数字 [0-9]

[:graph:] Characters that are both printable and visible. (A space is print-

able, but not visible, while an a is both.)

匹配所有可见字符 但不包含空格和TAB 就是你在文本文档中按键盘上能用眼睛观察到的所有符号

[:lower:] Lower-case alphabetic characters.

小写 [a-z]

[:print:] Printable characters (characters that are not control characters.)

匹配所有可见字符 包括空格和TAB

能打印到纸上的所有符号

[:punct:] Punctuation characters (characters that are not letter, digits, con-

trol characters, or space characters).

特殊输入符号 +-=)(*&^%$#@!~`|"'{}[]:;?/>.

注意它不包含空格和TAB

这个集合不等于^[a-zA-Z0-9]

[:space:] Space characters (such as space, tab, and formfeed, to name a few).

[:upper:] Upper-case alphabetic characters.

大写 [A-Z]

[:xdigit:] Characters that are hexadecimal digits.

16进制数 [0-f]

使用方法:

[root@seker ~]# grep --color '[[:alnum:]]' /etc/passwd

正则表达式及字符处理

目标文件/etc/passwd,使用grep命令或egrep

1.显示出所有含有root的行:

2.输出任何包含bash的所有行,还要输出紧接着这行的上下各两行的内容:

3. 显示出有多少行含有nologin。

4.显示出那些行含有root,并将行号一块输出。

5.显示出文件中

6.新建用户

abominable

abominate

anomie

atomize

编写正则表达式,将他们匹配出来

egrep 'a.omi(nabl|nat|z|)e' /etc/passwd

7.建四个用户

Alex213sb

Wpq2222b

yH438PIG

egon666

egon

过滤出用户名组成是字母+数字+字母的行

[root@MiWiFi-R3-srv ~]# egrep '^[a-Z]+[0-9]+[a-Z]+' /etc/passwd

8.显示出/etc目录下所有包含root的文件名

9. 过滤掉/etc/ssh/sshd_config内所有注释和所有空行

grep -v '^#' /etc/ssh/sshd_config |grep -v '^ *$'

三 sed

sed

流编辑器 stream editer,是以行为单位的处理程序

sed 流编辑器 stream editer

语法

sed [options] 'command' in_file[s]

options 部分

-n

-e

-i

-f

command 部分

'[地址1,地址2] [函数] [参数(标记)]'

定址的方法 1.数字 2.正则

数字

十进制数

1 单行

1,3范围 从第一行到第三行

2,+4 匹配行后若干行

4,~3 从第四行到下一个3的倍数行

2~3第二行起每间隔三行的行

$尾行

1!除了第一行以外的行

正则

正则必须用//包裹起来

扩展正则需要用 -r 参数或转义

数字定址:sed -n '1p' /etc/passwd

正则定址:sed -n '/^root/p' /etc/passwd

正则介绍

^行首

$行尾

.除了换行符以外的任意单个字符

*前导字符的零个或多个

.*所有字符

[]字符组内的任一字符

[^]对字符组内的每个字符取反(不匹配字符组内的每个字符)

^[^]非字符组内的字符开头的行

[a-z] 小写字母

[A-Z] 大写字母

[a-Z] 小写和大写字母

[0-9] 数字

>单词尾

扩展正则 加 -r 参数 或转义

sed -n '/roo?/p' /etc/passwd

sed -rn '/roo?/p' /etc/passwd

? 前导字符零个或一个

+ 前导字符一个或多个

abc|def abc或def

a(bc|de)f abcf 或 adef

x{m} x出现m次

x{m,} x出现m次至多次(至少m次)

x{m,n} x出现m次至n次

函数

增删改

a 后插

c 替换

i 前插

d 删除

输入输出

p 打印匹配的行 一般和 -n 参数连用,以屏蔽默认输出

r 从文件中读入

w 写入到文件中

控制流

! 命令取反 例: 1!d 删除第一行以外的行

{} 命令组合 命令用分号分隔 {1h;G} 可以理解为 -e 参数的另一种写法

= 打印行号(输入行的号码,而非处理的次数行号) 例如: sed -n '2{=;p}' infile

n 读入下一行到模式空间 例:'4{n;d}' 删除第5行

N 而是追加下一行到模式空间,再把当前行和下一行同时应用后面的命令

替换

s 字符串替换 s/old/new/

$ sed -n 's/root/ABCDEF/p' /etc/passwd

ABCDEF:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/ABCDEF:/sbin/nologin

$ sed -n 's/root/ABCDEF/gp' /etc/passwd

ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash

operator:x:11:0:operator:/ABCDEF:/sbin/nologin

$ sed -n 's/root/ABCDEF/2p' /etc/passwd

root:x:0:0:ABCDEF:/root:/bin/bash

$ sed -n 's/root/ABCDEF/3p' /etc/passwd

root:x:0:0:root:/ABCDEF:/bin/bash

$ sed -n 's/root/ABCDEF/gp' /etc/passwd

ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash

operator:x:11:0:operator:/ABCDEF:/sbin/nologin

$

()保存被匹配的字符 以备反向引用N时使用 最多9个标签 标签顺序从左至右

&替换时使用,在不定义标签时使用(反向引用)

试做:

删除第一个单词

删除最后一个单词

将第一个单词和最后一个单词兑换位置

y 字符替换(变形)

工作模式 模式空间和保持空间介绍

$ sed '1{p;p}' a.txt

11111111

11111111

11111111

22222222

33333333

44444444

55555555

66666666

$

置换 模式空间和保持空间(暂存空间)

h 把模式空间内容覆盖到保持空间中

H 把模式空间内容追加到保持空间中

g 把保持空间内容覆盖到模式空间中

G 把保持空间内容追加到模式空间中

x 交换模式空间与保持空间的内容

# cat test.sh

1111111

2222222

3333333

4444444

# sed '{1h;2,3H;4G}' ./test.sh

1111111

2222222

3333333

4444444

1111111

2222222

3333333

# sed '{1h;2x;3g;$G}' ./test.sh

1111111

1111111

2222222

4444444

2222222

#

试做题

将第一行插入到每个偶数行的后面

$ sed '1h;0~2G' a.txt

11111111

22222222

11111111

33333333

44444444

11111111

55555555

66666666

11111111

$

颠倒输出

$ sed '1!G;h;$!d' rev.txt

xyz

def

abc

$

脚本方法

-f 参数 引用脚本(脚本的末尾不能有空格制表符或其他文本)

# cat sed.sh

2,4d

s/777/seker/

s/999/seker&seker/

# sed -f sed.sh test.txt

1111111

5555555

6666666

seker7777

8888888

seker999seker9999

#

在脚本中指明解释器为sed

# cat sed.sh

#!/bin/sed -f

2,4d

s/777/seker/

s/999/seker&seker/

# ./sed.sh test.txt

1111111

5555555

6666666

seker7777

8888888

seker999seker9999

#

高级流控命令 b分支 t测试

分支命令用于无条件转移,测试命令用于有条件转移

分支 branch

跳转的位置与标签相关联

如果有标签则跳转到标签所在的后面行继续执行

如果没有标签则跳转到脚本的结尾处.

标签 以冒号开始后接标签名 不要在标签名前后使用空格

跳转到标签指定位置

[root@stu254 ~]# grep seker /etc/passwd

seker:x:500:500::/home/seker:/bin/bash

[root@stu254 ~]#

[root@stu254 ~]# grep seker /etc/passwd |sed ':top;s/seker/blues/;/seker/b top;s/5/555/'

blues:x:55500:500::/home/blues:/bin/bash

[root@stu254 ~]#

命令分析:让单次替换(cmd1)循环执行,直到条件不满足

:top; 定义一个top标签

s/seker/blues/; cmd1

/seker/b top; 如果模式匹配则跳转到top标签

s/5/555/ 当上一条模式不匹配时,既会继续执行这一条

选择执行

[root@stu254 ~]# grep 'seker' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/'

blues:x:66600:500::/home/seker:/bin/bash

[root@stu254 ~]#

zorro:x:501:501::/home/zorro:/bin/bash

[root@stu254 ~]# grep 'zorro' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/'

zorro:x:6665501:501::/home/zorro:/bin/bash

[root@stu254 ~]#

命令分析: 执行cmd1,再去模式匹配,成功则跳转到cmd3开始执行,否则(模式不匹配)会按命令顺序逐个执行

s/seker/blues/; cmd1

/seker/b end;

s/5/555/; cmd2

:end;

s/5/666/ cmd3

另一种选择执行

[root@stu254 ~]# grep 'seker' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/'

blues:x:66600:500::/home/seker:/bin/bash

[root@stu254 ~]# grep 'zorro' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/'

zorro:x:55501:501::/home/zorro:/bin/bash

[root@stu254 ~]#

命令分析: 执行cmd1;模式匹配cmd2成功则执行cmd3;否则执行cmd2,再跳转到脚本末尾

s/seker/blues/; cmd1

/seker/b end;

s/5/555/; cmd2

b;

:end;

s/5/666/ cmd3

测试命令,如果前一个替换命令执行成功则跳转到脚本末尾 (case结构)

[root@stu254 ~]# grep 'seker' /etc/passwd |sed 's/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/'

ABC:x:500:500::/home/seker:/bin/bash

[root@stu254 ~]# grep 'zorro' /etc/passwd |sed 's/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/'

zorro:x:501:501::/DEF/zorro:/bin/bash

[root@stu254 ~]#

与标签关联,跳转到标签位置

[root@stu254 ~]# grep 'seker' /etc/passwd |sed 's/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/'

ABC:x:500:500::/home/seker:/bin/XYZ

[root@stu254 ~]#

[seker@seker ~]$ grep 'zorro' /etc/passwd |sed 's/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/'

zorro:x:501:501::/DEF/zorro:/bin/bash

四 awk

awk -F: '$1 == "root"{print $1,NR,NF}' /etc/passwd

awk -F: 'NR>20 || NR<3{print $1,$3,$NF}' /etc/passwd

awk -F: 'NR>1 && NR<3{print $1,NR,NF}' /etc/passwd

awk -F: 'NR>1 && NR<4{print $1,NR,NF}' /etc/passwd

awk -F: '$1~/^r/{print $1,NR,NF}' /etc/passwd

awk -F: '/^root/{print $1,NR,NF}' /etc/passwd

username=root

awk -v var=$username -F: '$1 == var{print $1,NR,NF}' /etc/passwd

打印uid在30~40范围内的用户名。

打印第5-10行的行号和用户名

打印奇数行

打印偶数行

打印字段数大于5的行

打印UID不等于GID的用户名

打印没有指定shell的用户

awk详细

语法

awk [options] 'commands' files

option

-F 定义字段分隔符,默认的分隔符是连续的空格或制表符

使用option中的-F参数定义间隔符号

用$1,$2,$3等的顺序表示files中每行以间隔符号分隔的各列不同域

NF变量表示当前记录的字段数

-v 定义变量并赋值 也可以借用次方式从shell变量中引入

command

读前处理 行处理 读后处理

1.读前处理 BEGIN{awk_cmd1;awk_cmd2}

2.行处理:定址 命令

定址方法: 正则,变量,比较和关系运算

正则需要用//包围起来

^行首

$行尾

.除了换行符以外的任意单个字符

*前导字符的零个或多个

.*所有字符

[]字符组内的任一字符

[^]对字符组内的每个字符取反(不匹配字符组内的每个字符)

^[^]非字符组内的字符开头的行

[a-z] 小写字母

[A-Z] 大写字母

[a-Z] 小写和大写字母

[0-9] 数字

>单词尾

扩展正则 加 -r 参数 或转义

sed -n '/roo?/p' /etc/passwd

sed -rn '/roo?/p' /etc/passwd

? 前导字符零个或一个

+ 前导字符一个或多个

abc|def abc或def

a(bc|de)f abcf 或 adef

x{m} x出现m次

x{m,} x出现m次至多次(至少m次)

x{m,n} x出现m次至n次

NR变量定址

NR 表示AWK读入的行数

FNR表示读入行所在文件中的行数

# awk '{print NR,FNR,$1}' file1 file2

1 1 aaaaa

2 2 bbbbb

3 3 ccccc

4 1 dddddd

5 2 eeeeee

6 3 ffffff

#

逻辑运算 可直接引用域进行运算

== >= <= != > < ~ !~

# awk 'NR==1 {print}' /etc/passwd

root:x:0:0:root:/root:/bin/bash

#

3.命令 {print $0}

4.读后处理 END {awk_cmd1;awk_cmd2;}

AWK变量

NR 当前记录的个数(全部文件连接后的统计)

FNR 当前记录的个数(仅为当前文件的统计,非全部)

FS 字段分隔符 默认为连续空格或制表符,可以使用多个不同的符号做分隔符 -F[:/]

OFS 输出字符的分隔符 默认是空格

# awk -F: 'OFS="=====" {print $1,$2}' /etc/passwd

root=====x

NF 当前读入行的字段个数

ORS 输出记录分隔符 默认是换行

# awk -F: 'ORS="=====" {print $1,$2}' /etc/passwd

root x=====bin x=====

FILENAME 当前文件名

引用shell变量的方法

# a=root

# awk -v var=$a -F: '$1 == var {print $0}' /etc/passwd

或者 把整个命令拆开传递,让shell变量外露,

# awk -F: '$1 == "'$a'" {print $0}' /etc/passwd

# a=NF

# awk -F: '{print $'$a'}' /etc/passwd

操作符

赋值

= += -= /= *=

逻辑与 逻辑或 逻辑非

&& || !

匹配正则或不匹配,正则需要用 /正则/ 包围住

~ !~

关系 比较字符串时要把字符串用双引号引起来

< <= > >= != ==

字段引用

$ 字段引用需要加$,而变量引用直接用变量名取

运算符

+ - * / % ++ --

转义序列

\ 自身

$ 转义$

制表符

退格符

回车符

换行符

责任编辑:

你可能感兴趣的:(linux正则表达式测试器)