Linux 学习之正则表达式
jinhucheung opened this issue · comments
1. 正则表达式-字符的模式
1.1 语系对正则表达式的影响
正则表达式中字符的编码顺序会对正则式匹配的结果造成影响
比如zh_CN和C语系的数字字母编码顺序:
- LANG=zh_CN : 0 1 2 3 4 ... a A b B c C ... z Z
- LANG=C : 0 1 2 3 4... A B C ... Z a b c ...z
所以我们需要指定编码,通常我们会指定LANG=C (ASCII码)
为了能规范这种差异,正则表达式中也存在特殊符号来表示一些字符,如下表
特殊符号 | 代表意义 |
---|---|
[:alnum:] | 代表大小写字母和数字,即0-9,A-Z,a-z |
[:alpha:] | 代表大小写字母,即A-Z,a-z |
[:blank:] | 空格与[TAB] |
[:cntrl:] | 键盘上控制键,即CR,LF,TAB,DEL等 |
[:digit:] | 代表数字 |
[:graph:] | 除空格与[TAB]外的其他字符 |
[:lower:] | 小写字母 |
[:upper:] | 大写字母 |
[:print:] | 代表任何可以被打印出来的字符 |
[:space:] | 任何会产生空白的字符,如空格,[TAB],CR等 |
[:punct:] | 代表标点符号,即" ' ? ! ; 等 |
[:xdigit:] | 代表十六进制数,即0-9,A-F,a-f |
1.2 支持正则式的命令
1.2.1 基础正则式命令: grep
基础正则式的特殊字符如下表
特殊符号 | 代表意义 |
---|---|
^word | 待查找字符串word在行首 |
word$ | 待查找字符串word在行尾 |
. | 代表一定有一个任意字符 |
\ | 转义字符 |
* | 重复零个到无穷个的前一个字符 |
[list] | 匹配list中的任意字符 |
[n1-n2] | 匹配编码从n1-n2的任意字符 |
[^list] | 匹配非list中的任意字符 |
{n,m} | 重复前一个字符n-m遍 |
1.2.2 扩展正则式命令: egrep
egrep与grep一样使用,其支持了更多的特殊字符
扩展正则式的特殊字符如下表
特殊符号 | 代表意义 |
---|---|
+ | 重复一个或一个以上的前一个字符 |
? | 重复零或一个的前一个字符 |
() | 匹配组: 如查找glad或good这两个字符,正则式:g(la |
()+ | 重复匹配组 |
1.2.3 分析stdin并处理筛选命令: sed
sed工具:分析stdin,并可以对数据进行替换/删除/增加/选取特定行的功能
sed的格式: sed [-nefri] function
命令参数:
n
打印模式e
直接在命令行处理,当进行多个function动作时须要指定i
直接修改文件r
使sed支持扩展正则式(默认支持基础正则式)f
将function写到文件中,读取该文件进行动作
function参数:
a
新增,形如'n1a str' : 在当前第n1行后增加str行c
替换, 形如'n1,n2c str',用str替换n1到n2行d
删除, 形如'n1,n2d',删除n1到n2行,删除n1到最后(n1,$d)i
插入,形如'n1i str',在当前第n1行前增加str行p
打印,形如'n1,n2p',打印n1到n2行,须要加-ns
替换,形如's/str1/str2/g' 全文搜索,将str2代替str1
1.3 文件格式化命令
1.3.1 格式化打印:printf
printf不是管道命令,其处理的是文本数据,当读取文件时,须先提出文件的内容,如$(cat filename)
printf的基本格式:printf '打印格式' 文本内容
其中打印格式如C语言的printf
比如我要打印如下格式的文本(test.txt),并去掉Name行
Name Chinese English Math Average
DmTsai 80 60 70 70
VBrid 70 60 65 65
可以使用如下命令
printf '%10s %5d %5d %5d %5.2f' $(cat test.txt|grep -v 'Name')
1.3.2 字段处理:awk
awk是管道命令. 其用分隔符(默认是空格或[TAB])将一行分隔成多个字段,并用变量$0,$1,$2...$n来表示整行,第1个字段,第2个字段...第n个字段
awk的基本格式 awk '条件1{动作1} 条件2{动作2}... 条件n{动作n}' filename
awk内置的变量
变量名称 | 意义 |
---|---|
$n | n为数字,其中0表示整行,其他表示第n个字段 |
NF | 每一行($0)的字段总数 |
NR | 目前awk处理的当前行号 |
FS | 目前的分隔符,默认是空格,设置分隔符可以 'BEGIN {FS="str"}' |
awk的条件逻辑运算符是> < >= <= == !=
例子:将1.3.1的例子test.txt添加总分字段'Total',重新打印处理
$ cat test.txt | \
> awk ' NR==1 {printf "%10s %10s %10s %10s %10s %10s\n", $1,$2,$3,$4,$5,"Total"}
> NR>=2 {total=$2+$3+$4 printf "%10s %10d %10d %10d %10.2f %10.2f",$1,$2,$3,$4,$5,total}'
1.3.3 文件比较及补丁:diff与patch
当我们比较两个相识(新旧版本)的文本文件时,可以使用diff filename1 filename2
如果是打出补丁文件 diff -Naur filename1 filename2 > filename.patch
对文件进行补丁 patch -p0 < filename.patch
(新旧文件同目录中)
还原文件 patch -R -p0 < filename.patch