Shell正则表达式
正则表达式主要分为以下三种:
- 基本的正则表达式(Basic Regular Expression)
- 扩展的正则表达式(Extended Regular Expression)
- Perl的正则表达式(Perl Regular Expression)
基本的正则表达式
| 正则表达式 | 描述 | 示例 |
|---|---|---|
| \ | 转义符,将特殊字符进行转义,忽略其特殊意义 | a.b匹配a.b,但不能匹配ajb,.被转义为特殊意义 |
| ^ | 匹配行首,awk中,^则是匹配字符串的开始 | ^tux匹配以tux开头的行 |
| $ | 匹配行尾,awk中,$则是匹配字符串的结尾 | tux$匹配以tux结尾的行 |
| . | 匹配除换行符\n之外的任意单个字符,awk则中可以 | ab.匹配abc或bad,不可匹配abcd或abde,只能匹配单字符 |
| \[\] | 匹配包含在字符之中的任意一个字符 | cookl可以匹配cook或cool |
| \^ | 匹配\^字符之外的任意一个字符 | 123\^45不可以匹配1234或1235,1236、1237都可以 |
| - | 匹配\[\]中指定范围内的任意一个字符,要写成递增 | 0-9可以匹配1、2或3等其中任意一个数字 |
| ? | 匹配之前的项1次或者0次 | colou?r可以匹配color或者colour,不能匹配colouur |
| + | 匹配之前的项1次或者多次 | sa-6+匹配sa-6、sa-666,不能匹配sa- |
| * | 匹配之前的项0次或者多次 | co*l匹配cl、col、cool、coool等 |
| () | 匹配表达式,创建一个用于匹配的子串 | ma(tri)?匹配max或maxtrix |
| {n} | 匹配之前的项n次,n是可以为0的正整数 | 0-9{3}匹配任意一个三位数,可以扩展为0-90-90-9 |
| {n,} | 之前的项至少需要匹配n次 | 0-9{2,}匹配任意一个两位数或更多位数 |
| {n,m} | 指定之前的项至少匹配n次,最多匹配m次,n<=m | 0-9{2,5}匹配从两位数到五位数之间的任意一个数字 |
| | | 交替匹配|两边的任意一项 | ab(c|d)匹配abc或abd |
POSIX字符类
POSIX字符类是一个形如: ... :的特殊元序列,可用于匹配特定的字符范围。
| 正则表达式 | 描述 | 示例 |
|---|---|---|
| :alnum: | 匹配任意一个字母或者数字字符 | \[:alnum:]+ |
| :alpha: | 匹配任意一个字母字符(包括大小写字母) | \[:alpha:]{4} |
| :blank: | 空格与制表符(横向和纵向) | \[:blank:]* |
| :digit: | 匹配任意一个数字字符 | \[:digit:]? |
| :lower: | 匹配小写字母 | \[:lower:]{5,} |
| :upper: | 匹配大写字母 | (\[:upper:]+)? |
| :punct: | 匹配标点符号 | \[:punct:] |
| :space: | 匹配一个包括换行符、回车等在内的所有空白符 | \[:space:]+ |
| :graph: | 匹配任何一个可以看得见的且可以打印的字符 | \[:graph:] |
| :xdigit: | 任何一个十六进制数(即:0-9,a-f,A-F) | \[:xdigit:]+ |
| :cntrl: | 任何一个控制字符(ASCII字符集中的前32个字符) | \[:cntrl:] |
| :print: | 任何一个可以打印的字符 | \[:print:] |
元字符
元字符(meta character)是一种Perl风格的正则表达式,只有一部分文本处理工具支持它,并不是所有的文本处理工具支持。
| 正则表达式 | 描述 | 示例 |
|---|---|---|
| \b | 单词边界 | \bcool\b 匹配cool,不匹配coolant |
| \B | 非单词边界 | cool\B 匹配coolant,不匹配cool |
| \d | 单个数字字符 | b\db 匹配b2b,不匹配bcb |
| \D | 单个非数字字符 | b\Db 匹配bcb,不匹配b2b |
| \w | 单个单词字符 | \w 匹配1或a,不匹配& |
| \W | 单个非单词字符 | \W 匹配&,不匹配1或a |
| \n | 换行符 | \n 匹配一个新行 |
| \s | 单个空白字符 | x\sx 匹配x x,不匹配xx |
| \S | 单个非空白字符 | x\S\x 匹配xkx,不匹配xx |
| \r | 回车 | \r 匹配回车 |
| \t | 横向制表符 | \t 匹配一个横向制表符 |
| \v | 垂直制表符 | \v 匹配一个垂直制表符 |
| \f | 换页符 | \f 匹配一个换页符 |
grep, sed和awk命令概述
| 命令 | 特点 | 场景 |
|---|---|---|
| grep | 过滤 | grep命令过滤速度是最快的 |
| sed | 替换,修改文件内容,取行 | 进行替换/修改文件内容 取出某个范围的内容 |
| awk | 取列,统计计算 | 取列 对比,比较 >= <= != 统计,计算(awk数组) |
grep命令
选项 含义
-E ==egrep 支持正则扩展
-A after -A3 匹配你要的内容并且显示接下来的3行
-B before -B3 匹配你要的内容并且显示上面的3行
-C context -C3 匹配你要的内容并且显示上下3行
-c 统计出现了多少行,类似于wc -l
-v 取反 排除(行)
-n 显示行号
-i 忽略大小写
-w 精确匹配
sed命令
sed stream editor 流编辑器,sed把处理的内容(文件)当做是水,源源不断的进行处理,直到文件末尾,此命令执行数据如下:
- 每次读取一行数据内容;
- 根据提供的规则命令行匹配并修改数据。注意,sed 默认不会直接修改源文件数据,而是会将数据复制到缓冲区中,修改也仅限于缓冲区中的数据;
- 将执行结果输出。
当一行数据匹配完成后,它会继续读取下一行数据,并重复这个过程,直到将文件中所有数据处理完毕。
sed命令的基本格式如下:
bash
[root@localhost ~]# sed [选项] [脚本命令] 文件名
sed 命令常用选项以及含义
| 选项 | 含义 |
|---|---|
| -e 脚本命令 | 该选项会将其后跟的脚本命令添加到已有的命令中。 |
| -f 脚本命令文件 | 该选项会将其后文件中的脚本命令添加到已有的命令中。 |
| -n | 默认情况下,sed 会在所有的脚本指定执行完毕后,会自动输出处理后的内容,而该选项会屏蔽启动输出,需使用 print 命令来完成输出。 |
| -i | 此选项会直接修改源文件,要慎用。 |
sed格式
| 命令 | 选项 | (s)sed命令功能(g)修饰符 | 参数(文件) |
|---|---|---|---|
| sed | -r | 's#word1#word2#g' | cut.txt |
sed命令核心功能:增删改查
| 功能 | |
|---|---|
| s | 替换substitute |
| p | 显示print |
| d | 删除delete |
| cai | 增加c/a/i |
sed s 替换命令
此命令的基本格式为:
bash
[address]s/pattern/replacement/flags
其中,address 表示指定要操作的具体行,pattern 指的是需要替换的内容,replacement 指的是要替换的新内容
其中常用的flags标记如下表所示:
| flags标记 | 功能 |
|---|---|
| n | 1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这是就用到这个标记; |
| g | 对数据中所有匹配到的内容进行替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A; |
| p | 会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用。 |
| w file | 将缓冲区中的内容写到指定的 file 文件中; |
| & | 用正则表达式匹配的内容进行替换; |
| \n | 匹配第 n 个子串,该子串之前在 pattern 中用 () 指定。 |
| \ | 转义(转义替换部分包含:&、\ 等)。 |
s --> substitute 替换
g --> global 全局替换每行所有匹配的内容,sed默认只替换每行第一个匹配的内容
-n 选项会禁止 sed 输出,但 p 标记会输 出修改过的行,将二者匹配使用的效果就是只输出被替换命令修改过的行。
| 替换格式 |
|---|
| s###g |
| s///g |
| s@@@g |
| 三个相同的字符就行 |
sed p 命令
此命令格式为:
bash
[address]p
| 查找格式 | |
|---|---|
| '3p' | 指定行号进行查找 |
| '1,5p' | 指定行号范围进行查找 |
| '/zhang/p' | 类似于grep,过滤,//里面可以写正则 |
| '/10:00/,/11:00/p' | 表示范围的过滤 |
| '1,/zhang/p' | 混合 |
sed d 删除命令
此命令基本格式如下:
bash
[address]d
如果需要删除文本中的特定行,可以用 d 脚本命令,它会删除指定行中的所有内容。但使用该命令时要特别小心,如果你忘记指定具体行的话,文件中的所有内容都会被删除。
bash
[root@localhost ~]# sed 'd' data.txt //什么也不输出,成了空文件
[root@localhost ~]# sed '3d' data.txt //删除data.txt文件内容中的第3行
[root@localhost ~]# sed '2,3d' data.txt //删除data.txt文件内容中的第2,3行
[root@localhost ~]#sed '/1/,/3/d' data.txt //删除第1~3行的数据
sed-增加cai
| 命令 | |
|---|---|
| c | replace 代替这行的内容 |
| a | append 追加,向指定的行或每一行追加内容(行后面) |
| i | insert插入,向指定的行或每一行插入内容(行前面) |
sed c 替换脚本命令
该命令基本格式如下:
bash
[address]c\用于替换的新文本
例如:
bash
[root@localhost ~]# sed '3c\
> This is a changed line.' data.txt
This is line number 1.
This is line number 2.
This is a changed line.
This is line number 4. //修改第3行的数据内容
awk命令
awk命令
awk命令的基本格式为:
bash
[root@localhost ~]# awk [选项] '脚本命令' 文件名
此命令常用的选项及各自含义:
| 选项 | 含义 |
|---|---|
| -F fs | 指定以 fs 作为输入行分隔符,awk 命令默认分隔符为空格或制表符。 |
| -f file | 从脚本文件中读取 awk 脚本指令,以取代直接在命令行中输入指令。 |
| -v var=val | 在执行处理过程之前,设置一个变量 var,并给其设备初始值为 val。 |
awk的脚本命令部分,由2部分组成,分别为匹配规则和执行命令,如下所示:
bash
'匹配规则{执行命令}'
这里的匹配规则,和 sed 命令中的 address 部分作用相同,用来指定脚本命令可以作用到文本内容中的具体行,可以使用字符串(比如/demo/,表示查看含有demo字符串的行)或者正则表达式指定。
注意:整个脚本命令是用单引号('')括起,而其中执行的命令部分需要用大括号{}括起来。
在 awk 程序执行时,如果没有指定执行命令,则默认会把匹配的行输出;如果不指定匹配规则,则默认匹配文本中所有的行。
awk之行与列
| 名词 | awk中叫法 | 说明 |
| 行 | 记录record | 每一行默认通过回车分割 |
| 列 | 字段, 域, field | 每一列默认通过空格分割 |
| awk中行和列结标记都是可以修改的 |
| 内置变量 | |
|---|---|
| NR | Number of Record 记录号,行号 |
| NF | Number of Field 每行有多个字段(列)$NF表示最后一列 |
| FS | -F: ===-vFS=:字段分隔符,每个字段结束标记 |
| OFS | Out Field Separator 输出字段分隔符(awk显示每一列的时候,每一列之间通过什么分割,默认是空格) |
awk取行
| awk | |
|---|---|
| NR==1 | 取出第一行 |
| NR>=1 && NR<=5 | 取出第1行到第5行 |
| /101/, /105/ | 取出101到105行的内容 |
| 符号 | > < == >= <= != |
awk取列
| awk | |
|---|---|
-F |
指定分隔符,指定每一列结束标记(默认是空格,连续的空格,tab键) |
| $Number | 取出某一列 |
$0 |
表示取整行的内容 |
$NF |
表示取最后一列的内容 |
awk之模式匹配
| awk | -F" /+" | 'NR==3{print $3}' |
|---|---|---|
| 命令 | 选项 | 条件(动作)'pattern{action}' |
可以作为awk的条件有:
比较符号:> < >= <= == !=
正则表达式:~包含;!~不包含
模式汇总
| 模式 | 含义 |
|---|---|
| BEGIN{statements} | awk读取文件之前执行一次statements |
| END{statements} | awk读取文件之后执行一次statements |
| expression{statements} | 每碰到一个使expression为真(值为非零或非空)的输入行,statements就执行 |
例如:
| 命令 (条件 'pattern{action}') | 解释 |
|---|---|
| awk -F " " '{ sum += $1 }; END { print sum }' file | 将file文件中以空格为分隔符分割后第一个数据求和 |
| awk -F " " 'NF\>100{print NF}' file | 空格为分隔符,打印出最后一列数据大于100的数 |
| awk -F " " 'NR>=1&&NR<=3{print $NF}' file | 打印第1行到第3行的最后一列数据 |
| awk -F "," -v val={input1} '{if(NR\>1) {freq=8;if((val-freq)>10) {exit 1}}}' csvfile | 处理csv文件的第8列数据,去除第一行数据,当数据与输入数据相差10时,退出1;shell脚本中可通过$?判断返回值 |
awk数组
| shell数组 | awk数组 | |
|---|---|---|
| 形式 | array0 = mary array1=jack | array0 = mary array1=jack |
| 使用 | echo {array\[0\]} {array1} | print array0 array1 |
| 批量输出数组内容 | for i in {array\[\*\]} do echo i done | for (i in array) print arrayi |