Linux学习笔记2——正则表达式

基本正则表达式

基本字符(元字符):. * [ \ ^ $(圆点,星号,中括号,反斜线,尖号,dollar号)

  1. .匹配任意字符

  2. [ ]为集合,其中,圆点,星号和反斜线三个字符在集合中的时候表示自身

    中括号内,“ - ”减号表示一个区间

    [a-zA-Z0-9]  # 表示大小写字母或者数字
    

    如果单纯表示减号这个符号,需要将减号放在集合的末尾

    [ad-]  # 表示a,d,-三个字符
    

    如果要表示中括号自己:

    [][]  # 表示左右中括号组成的集合
    
  3. ^在集合的开头表示补集

    [^a-z]  # 表示任意一个非小写字母的字符;\[^][] 表示任意一个非中括号的字符。
    

    如果不放在开头,则仅表示自身

    [a-z^]  # 表示小写字母和^字符
    
  4. 串接:

    [0-9].[A-Z].  # 表示一个四字符的字符串,其中第一个字符为数字,第三个字符为大写字母
    
  5. 重复:单字符后跟*表示这个字符重复0次或任意次:[A-Z][0-9]*

  6. $在尾部的时候表示仅匹配行尾,不位于行尾的时候仅表示自身:123$表示匹配文件中行尾的123

    ^在首部(注意,这里不是在集合的首部)的时候表示匹配行首,否则仅匹配自身

    ^123  # 表示以123开头的行
    
    Hel^lo  # 仅与字符串Hel^lo匹配
    

正则表达式扩展BRE:

  1. ()表示分组:
   (xy)*  # 表示可以重复任意次或者0次的xy串

也可以用于表示逻辑“或”

(pink|green)  # 与pink或者green都可以匹配
 ```powershell
 a+  # 加号表示至少一次的a
 a? # 问号表示重复0次或者1次的a
 \{m,n\}  # 表示至少要有m次,最多有n次
 [0-9]\{6,8\}  # 表示6到8位数字组成的字符串
 ```
  1. 一些特殊的预定义:表示特殊含义的组合

    1. [[:xdigit:]] 表示十六进制数字的集合

    2. \d表示任意一个数字

    3. \D表示非数字


正则筛选工具命令

行筛选grep

grep 的语法格式:grep 模式 文件列表名

基本选项:

  1. -n 显示的时候每行前显示行号

  2. -v 显示所有不包含查找模式的行(反向搜索)

  3. -i 忽略大小写

grep -n main *.c # 在当前文件夹下,对所有以.c为文件名结尾的文件检索,查找含有字符串“main"的行,并打印行号  ,如果有不止一个.c 文件,还会输出文件名
       
grep -v  '[Dd]isable'  dev.stat>dev.active  # 将文件dev.stat中所有不包含Disable 和 disable  的行选出,导出到文件dev.active中

注意:grep查找的时候,如果进行的是精准全字匹配,不需要打单引号。如果进行的是正则匹配,则需要对正则式打单引号

ps -ef | grep '^jiang' > progress.txt  # 列出jiang用户使用的进程名,并将这些进程信息导入到progress文件中

注意事项

grep的作用对象是行文件,准确来说是以回车为分界。

如果文本没有进行分行(即:整个文章就是一整段,没有任何回车),则grep会将整个文章视为一行进行筛选。

所以,如果需要grep进行匹配,首先要使用别的方式对文章进行分段,可以考虑使用sed流编辑或者tr翻译命令进行操作

sed 流编辑

基本用法1:sed '命令' 文件列表名

基本用法2:sed -e '命令1' -e '命令2' -e '命令3' 文件列表名: 合并多个命令

基本用法3:sed -f 命令文件 文件名列表:可以将命令写在一个文件中,在使用时读取

tail -f pppd.log | sed 's/145\.37\.23\.26/桥西/g'

tail命令列出log文件中新增的内容,sed后的引号内为指令,指令中,开头的s/为替换指令, 后面的145\.37\.23\.26表示被替换的内容,/桥西表示替换的内容为桥西,/g表示,在这一行中如果这个IP地址多次出现,则全替换

tail -f pppd.log | sed -f sed.cmd  # 其中sed.cmd文件内容为: 's/145\.37\.23\.26/桥西/g'

效果与例1相同

整体替换

  1. \(\)在正则表示中,仅为了书写者方便逻辑判断,没有实际意义,不会与括号做匹配
[a-z]* -> number
\([a-z]\)* -> number

指令与指令效果相同

  1. 替换功能:\0 \1 \2…:\0表示整个正则表达式,\x表示正则表达式中第x个括号内的内容
    例:
s/ [\([0-9][0-9]\)] - [\([0-9][0-9]\)] - [\([0-9][0-9]*\)] / \3.\1.\2/g  # 将月-日-年的格式改为年-月-日

一个完整的实例

对test.c代码中,root -> val的val替换成num(这里root可以是其他名称的结构体变量),且不能影响代码中作为普通变量的val

sed -e 's/ \([a-zA-Z_][a-zA-Z0-9_]*\) -> val/ \1 -> num /g' > test.c

awk语言

基本使用:

  1. `awk '程序' 文件名列表`:
  2. `awk -f  程序文件名 文件名列表`:使用写好命令的文档直接运行

程序的结构:程序 执行条件 {动作}

  1. 一些细节:

    1. 每一行中,用空格分开的部分,叫做记录的 域 **
      内置变量中, $x 是第x域的内容,
      $0** 表示这一整行的内容
    2. 输入文件的每一行为一个记录, 默认变量NR表示行号
    3. awk自动对每行文本执行条件判断**(自动循环)**,满足执行的动作
  2. 执行条件:

    1. C语言类似的算符:< > <= == != || && !

    2. 正则匹配:格式:/regexpr/ ,即两个斜线中间写入正则表达式

    3. 特殊条件:

      • 不指定任何条件,对所有文本执行动作
      • BEGIN: 在对所有文本行处理之前执行的动作
      • END: 在对所有文本行处理之后执行的动作
  3. 动作

    1. 自定义变量

    2. 加减乘除以及逻辑操作

    3. 正则表达式匹配运算符**(用作条件判断)**:~ 以及!~
      例:$2 ~ "\[1-9][1-9]*"表示 第二个域上的文本,应该是“非0数字开头的纯数字字符串”

    4. 流程控制:

      • 条件判断if

      • 循环for

      • 打印格式

        print 变量1 变量2...

        printf("格式串", 变量1,变量2, ...)

ps -ef  |  awk '/guest/{printf("%s", $2);}'  # 表示:找到含有guest的行,并输出每一行第二个域的内容
awk  '{printf("%d  :  %s \n",  NR, $0);}' test.c  # 对test.c这个文件,逐行输出每一行的内容,并在开头表明行号
ls -s  |  awk '$1 > 2000 {print $2}'  # 前者罗列所有的文件以及对应的文件大小,后者筛选文件大小大于2000B的文件,并输出文件名

awk,sed,grep的使用区分

总体概括

  1. grep的操作对象是以回车为分解符的“行”。对每一行,进行格式匹配。

    1. 匹配方式1:精确查找,只有grep支持精确查找

      grep test data.log  # 在data.log中寻找含有test的行,并输出
      

      匹配方式2:正则查找

      grep 't*st' data.log  # 在data.log中寻找符合“t*st”正则式的行并输出
      
    2. grep在进行匹配的时候,仅仅是进行匹配。也就是说,并不要求这一行严格匹配输入的精确字符串或者正则字符串,只需要这一行里包括这个条件就可以

  2. sed的操作对象是数据流。也就是说,对sed命令来说,一个文件就是一个一字排开的超长二进制字符串,他在里面对输入的匹配格式进行匹配。如果找到了一段字符串符合匹配,就按照需求对这一段进行修改其余部分照常输出

    1. 匹配方式:正则查找

      sed 's/t*st/TEST/g' data.log # 在data.log文件中寻找含有“t*st”正则式的字符串,并将这个字符串修改为TEST,其余部分正常输出
      
    2. 注意,sed和awk的匹配模式里只有正则匹配(精确匹配被包含在了正则匹配里)

  3. awk的操作对象和grep相似,也是行。

    1. 匹配方式:正则匹配

      awk '/t*st/{printf("%d %s",NR,$0);}' data.log  # 对data.log文件中含有t*st的行,输出行号和完整行
      

使用场景

  1. grep和awk可以筛选出需要的行信息,但如果文章事先没有分行,则需要sed或者tr指令来分行
  2. sed能够对完整文章进行指定修改,但是没法筛选需要的正则式匹配的句子
  3. awk如果需要执行的操作很多,可以通过vim编写一个oper.awk文件,在里面编写两个单引号之间的内容(以上一个例子中的指令为例,写入.awk文件中的指令应该为/t*st/{printf("%d %s",NR,$0);},注意,写入文件的指令不需要带单引号),然后采用awk -f oper.awk来执行即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章