正则表达式
1、常用元字符
正则表达式常用的元字符如下:
元字符 | 说明 |
\d | 匹配数字,相当于[0-9] |
\D | 匹配非数字,相当于[^0-9] |
\w | 匹配字母或数字或汉字或下划线相当于:[0-9a-zA-z_] |
\W | 匹配任意不是字母、数字、汉字或下划线的字符 |
\s | 匹配任意的空白符,如空格、换行符、制表符等相当于:\t| |\n |
\S | 匹配任意不是空白符的字符 |
.(点号) | 匹配除了换行符以外的任意字符 |
[…] | 匹配方括号中的所有字符 |
[^…] | 儿配非方括号中的所有字符 |
2、连接符
在正则表达式中,匹配数字或者英文字母的书写非常不方便。因此,正则表达式引入了连接符“-”来定义字符的范围。
连接符 | 说明 |
[0-9] | 匹配数字,等价于\d 相当于:[0123456789] |
[a-z] | 匹配英文小写字母 |
[A-Z] | 匹配英文大写字母 |
[0-9a-zA-z] | 匹配数字或英文字母 |
3、限定符/重复字数
限定符,就是限定某个或某类字符出现的次数。常用的正则表达式限定符如下:
限定符 | 说明 |
+ (扩展) | 重复1次或更多次 |
* | 重复0次或更多次(任意次数) |
? (扩展) | 重复0次或1次(最多1次) |
{n} | 重复n次 |
{n,} | 重复n次或更多次(最少n次) |
{n,m} | 重复n到m次 |
4、定位符
在正则表达式中,定位符,说白了,就是限定某些字符出现的位置。常用的正则表达式定位符如下:
定位符 | 说明 |
^ | 限定开始位置的字符 |
$ | 限定结尾位置的字符 |
\b | 限定单词(字)边界的字符 |
\B | 限定非单词(字)边界的字符 |
5、转义字符
正则表达式本身有它的一套转义字符。需要转义的特殊字符: $ ( ) * + . [ ] ? \ / ^、{ } |
转义宇符 | 说明 |
\b | 退格 |
\n | 回车换行 |
\t | Tab符号 |
\f | 换页 |
\’ | 单引号 |
\” | 双引号 |
\v | 跳格( Tab,水平) |
\r | 换行 |
\\ | 反斜杠 |
\OOO | 八进制整数,范围为000~777 |
\xHH | 十六进制整数,范围为00~FF |
\uhhhh | 十六进制编码的Unicode字符 |
\数字 | 反向引用,数字最小为1,代表前面出现的匹配项,匹配项要用() |
6、扩展正则表达式
扩展正则表达式使用频率上没有基本表达式那么高,但依然很重要,很多情况下没有扩展正则是搞不定的,sed 命令使用扩展正则时需要加上选项 -r
。
? | 表示前置字符有 0 个或 1 个 |
+ | 表示前置字符有 1 个或多个 |
| | 表示匹配其中的一项即可 |
() | 表示分组,(a|b)b 表示可以匹配 ab 或 bb 子串,且命令表达式中可以通过 \1、\2 来表示匹配的变量 |
{} | 和基本正则中的大括号中意义相同,只不过使用时不用加 转义符号 |
一,sed
Sed是一个流编辑器。流编辑器用于对输入流(来自管道的文件或输入)执行基本的文本转换。虽然在某些方面类似于允许脚本编辑的编辑器(例如ed),但sed只对输入进行一次传递,因此效率更高。但是,sed在管道中过滤文本的能力使其与其他类型的编辑器特别不同。sed 的基本语法如下。
sed [选项] ‘command’ filename,其中 command:[定址] [函数] [参数(标记)]
1、选项简单说明
-n,表示安静模式。默认 sed 会把每行内容处理完毕后打印到屏幕上,加上选项后就不会输出到屏幕上
-e,如果需要用 sed 对文本内容进行多种操作,则需要执行多条子命令来进行操作
-i,默认 sed 不会直接修改文件,如果需要修改文件,就要指定 -i 选项
-f,如果命令操作比较多时,用 -e 会有点力不从心,这时需要把多个子命令写入脚本文件,使用 -f 选项指定执行该脚本
-r:如果需要支持扩展正则表达式,那么需要添加 -r 选项
2、单引号与双引号
command 可用单引号也可以用双引号
单引号:所有字符都被视为文字字符,即字符按照字面含义进行处理,而不进行变量或命令替换。这意味着如果您在单引号中使用了变量或命令,它们将被视为普通的文本字符。
双引号:允许变量和命令替换。在双引号中,可以使用$符号引用变量,也可以使用`符号包含命令。双引号会解释其中的变量和命令,并在替换文本中进行替换。
3、定址Address
定址不需要分隔符,默认情况下 sed 会对每一行内容进行处理,有时候我们不需要对所有内容进行操作,只需要修改一种一部分,比如 1-10 行,偶数行,或包括 hello 字符串的行
m | 第m行 |
m,n | 第m到n行 |
m,+n | 第m到m+n行 |
m~n | 从m开始每隔n行,如2~5 匹配 2,7,12… |
$ | 最后一行 |
/regexp/ | 正则表达式 如:sed ‘/hell/s/old/new/g’ sedtest |
m,/regexp/ | 从m行开始到匹配到正则表达式 |
m! | 除了第m行 如:sed ‘2!s/this/that/g’ sedtest |
4、替换命令s
子命令 s 为替换子命令,是平时 sed 使用最多的命令,因为支持正则表达式,功能很强大
基本语法:[address]s/pat/rep/flags
4.1、替换命令s-分隔符
分隔符常用反斜杠/。假设我们需要使用sed将输入源中的/bin/sed 替换为 /home/yufei/bin/sed,因为/是模式分隔符,我们不得不对它进行转义,即 \/,完整的命令:sed ‘s/\/bin\/sed/\/home\/yufei\/bin\/sed/’.结果看起来是正确的。但是整个 sed 命令看起来就有点难以阅读了。更何况一个不小心,就会把替换的命令写错,其实 sed 允许使用其它的分隔符的,比如: | @ ` ! %,最推荐的还是(|)
4.2、反向引用
有时候需要sed替换需要前面的匹配变量,匹配变量用\1表示,就是\+数字,数字最小为1,这时候sed必须用-r -E选项应为要使用()例子:
echo 0532-8881234|sed -E 's/(.*)-(.*)/\1/g' 输出:05328881234
注意使用扩展正则时候 sed就不能再用”|”作为分隔符了
二,awk
与sed相比,sed面向行与列的筛选,行筛选用前置过滤条件,列筛选用print函数,awk面向列,awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
awk的语法如下:
awk [options] 'script' var=value file(s) awk [options] -f scriptfile var=value file(s) 其实常用的格式如下 awk -F fs 'script' file(s)
1、基本工作原理
awk的工作原理
awk -F fs ‘BEGIN{ commands } pattern{ commands } END{ commands }’ file
一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,执行过程如下:
第一步,BEGIN语句块: 执行BEGIN{ commands }语句块中的语句,在awk开始从输入流中读取行 之前 被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
第二步,pattern语句块:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕,通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print }
,即打印每一个读取到的行,awk读取的每一行都会执行该语句块
第三步,END语句块:当读至输入流末尾时,执行END{ commands }语句块,在awk从输入流中读取完所有的行 之后 即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。
注意如果pattern或者END存在,测后面必须跟一个文件
常用方式:
awk -F fs 'BEGIN{ commands } { commands } END{ commands }' file //中间的patten可以省略 awk 'BEGIN{ commands }' //不需要file 因为没有 patten以及END 在读取文件前结束了 awk '{ commands } END{ commands }' file //没有开始 但有每一行的处理 以及结束 awk 'END{ commands }' file awk '{ commands }' file //最常用的方式这个是中间语句块
2、print函数
当使用不带参数的print时,它就打印当前行,当print的参数是以逗号进行分隔时如print $1,$2 输出结果会有空格 $1 $2;如果打印的时候用空格分隔,结果是沾粘起来的,print $1 $2,输出 $1$2,print 后面跟可以接三种形式参数:
①$:比如$0 当前行,$1:第一个参数,$NF:最后一个参数, $(NF-1):倒数第二个参数
②””:比如”test”,可以在打印的东西加入字符串常量
③var:比如NR:行号,BEGIN 自定义变量,以及函数返回值
3、过滤与if判断 ‘/match/ {if () print $0; else print $0}’
match 意思是获取含有”match”的行,下面的awk语句可以写成一行
$ awk '{ if ($3 >=60 && $4 >= 60) print $0,"=>","Pass"; else print $0,"=>","Fail"; }' student-marks Jones 2143 78 84 77 => Pass Gondrol 2321 56 58 45 => Fail RinRao 2122 38 37 => Fail Edwin 2537 87 97 95 => Pass Dayan 2415 30 47 => Fail
4、例子
①下面这个例子将 file里面第二个字段相加获得一个累加值
awk 'BEGIN{ sum=0; print "总和:" } { print $2"+"; sum+=$2 } END{ print "等于"; print sum }' file 总和: 1+ 2+ 3+ 4+ 5+ 等于 15
②打印文件中字符最长行的长度
awk '{ if (length($0) > max) max = length($0) } END { print max }' geeksforgeeks.txt
③特定字段匹配,
awk '{ if($3 == "B6") print $0;}' geeksforgeeks.txt
三,grep
grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,本质上是行过滤它能使用正则表达式搜索文本,并把匹配的行打印出来。用于过滤/搜索的特定字符。可使用正则表达式能配合多种命令使用,使用上十分灵活。
-a --text # 不要忽略二进制数据。 -A 3 # 显示该行之后3行。 -C 3 #显示该列之前后3行 -B 3 #显示该行之前3行 -c #计算符合范本样式的列数。 -R/-r #目录查找。 -E #使用扩展正则表达式。 -v # 反转查找。 -n # 显示行号 -w # 只显示全字符合的列。 -d<进行动作> --directories=<动作> # 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。 -e<范本样式> --regexp=<范本样式> # 指定字符串作为查找文件内容的范本样式。 -f<范本文件> --file=<规则文件> # 指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。 -F --fixed-regexp # 将范本样式视为固定字符串的列表。 -G --basic-regexp # 将范本样式视为普通的表示法来使用。 -h --no-filename # 在显示符合范本样式的那一列之前,不标示该列所属的文件名称。 -H --with-filename # 在显示符合范本样式的那一列之前,标示该列的文件名称。 -i --ignore-case # 忽略字符大小写的差别。 -l --file-with-matches # 列出文件内容符合指定的范本样式的文件名称。 -L --files-without-match # 列出文件内容不符合指定的范本样式的文件名称。 -P --perl-regexp # PATTERN 是一个 Perl 正则表达式 -q --quiet或--silent # 不显示任何信息。 -s --no-messages # 不显示错误信息。 -V --version # 显示版本信息。 -x --line-regexp # 只显示全列符合的列。 -y # 此参数效果跟“-i”相同。 -o # 只输出文件中匹配到的部分。 -m --max-count= # 找到num行结果后停止查找,用来限制匹配行数