jinhucheung / blog

学习笔记

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Linux 学习之正则表达式

jinhucheung opened this issue · comments

commented
commented

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行,须要加-n
  • s 替换,形如's/str1/str2/g' 全文搜索,将str2代替str1
commented

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