正则表达式

正则表达式在很多工具中都会用到,但是形式却不太一样的样子,比如说在VIM中,使用正则表达式的时候是在一般模式下通过两个斜杠。如下所示


但是在sed指令中却是这样的


但是正则的通用格式是/^[0-9]+bc$/g

正则表达式分基本正则和扩展正则,在一些工具中基本正则可以使用,但是扩展正则需要加指令才能支持

基本正则

对应字符有 ^ $ . [ ] *

符号

作用/解释

^

用于模式的最左侧,"^hello",表示以hello字符串为开头的行

$

用于模式的最右侧,"hello$",表示以hello字符串结尾的行

.

匹配任意一个有且只有一个字符,不能匹配空行

*

匹配前一个字符出现任意次数的字符串所在的行

[ ]

匹配括号内的字符

\转义字符




^$

这个合在一起就表示查找空行了

.*

因为.表示匹配一个字符,而*有表示.可以出现0次,一次,无数次,所以这里表示为匹配所有内容

[^abc]

括号里面的 ^ 和正常 ^ 的有区别,匹配除了a,b,c任意一个字符的其他字符

测试文本

Many years ago,when I was in middle school,a show called Supergirl was so hot that almost everyone was talking about it.Many girls became famous since the show. With the great success of this talent show,a lot of similar shows came into being. The public holds different opinions about these shows.

/^Many/g         # 匹配以Many为开头的行,所以第一行就会匹配到,注意其他地方出现了”Many“但不在首位置并不会被匹配

扩展正则

在基本正则的基础上增加了 ( ) { } ? + | 等字符

符号

作用/解释

( )

g(oo)d

{ }


?


+

1个或者多个

|

多个正则条件

修饰符

符号

作用/解释

g

全局,查找所有的匹配项。

i

将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。




grep

作为过滤,常配合管道符使用

cat  1.txt | grep "hello"
 cat  1.txt | grep -n "hello"          # -n参数   显示匹配字符所在行的行号
 cat  1.txt | grep -E "hello|world"      # -E参数  使用扩展正则表达式
 cat  1.txt | grep -v "hello"          # -v参数   获得文件中除“hello”之外的内容
 cat  1.txt | grep -i "hello"          # -i参数   忽略大小写
 cat  1.txt | grep -o "hello"          # -o参数   仅输出匹配过滤条件的字符,而不是匹配字符的那一整行都输出
grep  "^hello"  1.txt  
 

sed

sed的工作流程:


基本过程,sed是将文件都按行读取到模式空间中,然后未选中的行(不需要编辑的行)直接输出而选中的行做好编辑修改后,也打印出来,只是内容修改了,输出时行的位置没有变化,重要的是这里的修改只是模式空间中的数据进行了修改,文件本身的内容并没有改变。

语法:

sed   [ 选项 ]    [ sed内置的命令字符  ]   [ 文件 ]

选项:

参数

解释

-n

取消默认输出,sed默认会输出所有文本内容,使用-n参数后只输出选择的行

-i

直接对文件内容进行修改,不加 -i 时默认只是预览,不会对文件做实际修改

-r

使用扩展正则表达式

-e

它告诉sed将下一个参数解释为一个sed指令,只有当命令行上给出多个sed指令时才需要使用-e选项

-f

后跟保存了sed指令的文件

内置命令字符:

字符

解释

a

在指定的行后面追加新的一行或多行文本

d

删除指定行

i

在指定的行前面追加新的一行或多行文本

p

打印指定行

s/正则/替换内容/g

替换,通过正则找到目标,然后用替换内容替换即可

/ /

斜杠内填写正则来查找目标

# 打印
 sed  2p  test.txt    # 在这里我们选中了第二行作编辑(这里编辑的行为是打印),按sed流程,所有的行都会输出
 sed  -n  2p  test.txt     # 这样就只会打印第二行,n参数就是让没被选中的行不打印
 sed  -n  2,3p  test.txt            # 显示第二行,第三行的内容
 sed  -n  2,+3p  test.txt            # 显示第二行及其下面的三行内容,即2,3,4,5行
 sed  -n  2,$p  test.txt            # 显示第二行一直到结尾
 
 # 正则
 sed  -n  "/god/p"  test.txt    # 这里用的其实是正则来查找有god的行然后打印
 
 #删除
 sed  2d  test.txt        # 删除第二行,sed会输出文件中其余的行的内容
 
 # 替换
 # sed  s/要查找的字符串/要替换的字符串/g    file.txt     要查找的字符串是用正则的方法
 sed  s/hello/hi/g  test.txt            # 将hello换成hi
 
 sed  "2ahello"  test.txt     # 在第二行的后面追加一行,内容是hello
 sed  "3iworld"  test.txt     # 在第三行的前面追加一行,内容是world
 sed  "2ahello,\nworld"  test.txt     # 这里的\n是转义字符,相当于在第二行后面追加两行,即第三行的内容是hello,,第4行是world                         由此可见,sed是支持转义字符的
 
 sed  -e  s/hello/hi/g  -e s/world/wd/g  test.txt     # 一个指令执行多次方法
 
 
 
 
 查找目标--操作指令符--修改的内容

awk

awk是一个极其强大的文本处理工具,空格作为分隔符

awk的核心功能是:

+ 以行读取,以列操作文件内容
     + 文本格式化

awk格式:

awk  '{action}'  filename
 awk  'pattern'  filename      # pattern是正则
 awk  'pattern {action}'  filename
 awk  'pattern {action}  pattern {action}...'  filename

字符

解释

-F

改变输入分割符FS,默认是以空格作为字段的分割符,我们通过这个就可改成其他的了

-v

定义或修改一个awk内部的变量

-f

从脚本文件中读取awk命令

内置变量

符号

解释

FS

输入分割符

OFS

输出分割符

NR

行号

NF

当前行的字段数

模式

符号

解释

BEGIN


END


/正则/{动作}


示例

awk '{print "第一列的内容是:"$1}'  1.txt   # 输出第二列的内容
 # $0  代表所有列的内容
 # $NF表示当前行分割后的最后一列    $0和$NF都是内置的变量
 # NF代表分割后字段的数量
 # $n代表第几列的内容
 # $n不能用双引号包裹
awk  'END {print "hello"} {print $1}'
# 变量
 awk  'NR==5{print $0}'  test.txt      # 在这里NR==5是一个模式,就是会找到第5行,而后面的是动作,将打印该行所有的字段。所以这句指令会打印第5行内容。在awk中NR是一个变量,代表的是行号
 awk  'NR==5,NR==7{print NR,$0}'  test.txt     # 打印第5,第7行,同时也会在前面显示行号
awk  '/^hello/,/world$/{print  $0}'  test.txt       # 左边是正则,右边是方法,多个正则用以逗号隔开,每个正则用两个斜杠/ /

输入分隔符

awk在逐行处理文本的时候,以输入分割符(默认是空格)为单位,将文本切成多个片段


本来文本是上面的方框中内容输入awk中,然后awk用空格去切割文本,可是不存在空格,也就是说这段文本每一行都只有一个片段,只有$1,如果我们修改了FS,就不再是按照空格分割文本了,而是用冒号来分割文本。

我们不仅可以用 -v 参数修改变量值FS,也可以用 -f 参数直接修改FS,从图可以看出结果是一样的


输出分割符OFS

输出类似于输入