正则表达式

  • 正则表达式是通过一些特殊字符的排列,用以查找、替换、删除一行或多行文字字符串。
  • 正则表达式并不是一个工具程序,而是一种字符串处理的标准依据,如果想要以正则表达式的方式处理字符串,就得要使用支持正则表达式的工具程序才行,这类工具程序很多,例如:vi、grep、sed、swk等。

正则表达式字符: 正则表达式 – 语法 | 菜鸟教程

正则表达式几个工具的使用:

1、grep

grep高级参数: grep [-A] [-B] [–color=auto] ‘搜寻字符串’ filename 参数: -A:后面可加数字,为after的意思,除了匹配行,后续的 n 行也列出来; -B:后面可加数字,为before的意思,除了匹配行,前面的 n 行也列出来; –color=auto:可将选取的数据列出颜色。

>> dmesg | grep -n -A3 -B2 --color=auto 'eth'
# 将匹配行及该行的前两行与后三行显示出来

grep + 正则表达式:

例1:查找特定字符串:
>> grep -in 'the' regular_express.txt  --> 输出含‘the’且不区分大小写的行

例2:利用中括号[]来查找集合字符:
>> grep -n '[^a-z]oo' regular_express.txt  --> 输出oo前不是小写字母的行

例3:行首与行尾字符^$:
>> grep -n '^[^a-zA-Z]' regular_express.txt  --> 输出不以英文字母开头的行
# ^在[]内外是不一样的,在[]内代表“反向选择”,在[]外代表定位在行首
>> grep -v '^$' /etc/syslog.conf | grep -v '^#'  --> 输出不是空行、不以#开头的行

例4:任意一个字符.与重复字符*:
. : 代表一定有一个任意字符;
* : 代表重复前一个字符0到无穷多次,为组合形态。
>> grep -n 'g.*g' regular_express.txt  --> 输出g...g中间可以是任意字符的行
>> grep -n '[0-9][0-9]*' regular_express.txt  --> 输出包含任意数字的行

例5:限定连续RE字符范围{}:
{}:限定字符串的范围
>> grep -n 'o\{2\}' regular_express.txt  --> 匹配包含两个o的行
>> grep -n 'go\{2,5\}g' regular_express.txt  --> 匹配g..g之间包含2-5个o的行
2、sed

功能: 管道命令,可以分析standard input,而且sed还可以将数据进行替换、删除、新增、选取特定行等。

格式: sed [-nefr] [动作] 参数: -n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。 -e :直接在命令列模式上进行 sed 的动作编辑; -f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作; -r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法) -i :直接修改读取的文件内容,而不是输出到终端。

动作说明: [n1[,n2]]function n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』

function: a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~ c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行! d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚; i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行); p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~ s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

举例:

例1:以行为单位的新增/删除功能:  
>> nl /etc/passwd | sed '2,5d'  # 删除第2-5行
1   root:x:0:0:root:/root:/bin/bash
6   games:x:5:60:games:/usr/games:/usr/sbin/nologin
7   man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
8   lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
...

>> nl /etc/passwd | sed '2a drink tea'  # 第2行后加上"drink tea"
     1  root:x:0:0:root:/root:/bin/bash
     2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
drink tea
     3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
     4  sys:x:3:3:sys:/dev:/usr/sbin/nologin
     5  sync:x:4:65534:sync:/bin:/bin/sync
     6  games:x:5:60:games:/usr/games:/usr/sbin/nologin

>> nl /etc/passwd | sed '2i drink tea'  # 第2行前加上"drink tea"
     1  root:x:0:0:root:/root:/bin/bash
drink tea
     2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
     3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
     4  sys:x:3:3:sys:/dev:/usr/sbin/nologin
     5  sync:x:4:65534:sync:/bin:/bin/sync
     6  games:x:5:60:games:/usr/games:/usr/sbin/nologin

例2:以行为单位的替换与显示功能:  
>> nl /etc/passwd | sed '2,5c No 2-5 number'  # 将第2-5行替换为"No 2-5 number"
     1  root:x:0:0:root:/root:/bin/bash
No 2-5 number
     6  games:x:5:60:games:/usr/games:/usr/sbin/nologin
     7  man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
     8  lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin

>> nl /etc/passwd | sed -n '5,7p'  # 显示第5-7行
5   sync:x:4:65534:sync:/bin:/bin/sync
6   games:x:5:60:games:/usr/games:/usr/sbin/nologin
7   man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

例3:部分数据的查找并替换的功能:

sed 's/要被替换的字符串/新的字符串/g'

>> /sbin/ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:16:3e:00:27:71  
          inet addr:172.19.90.208  Bcast:172.19.95.255  Mask:255.255.240.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:242073 errors:0 dropped:0 overruns:0 frame:0
          TX packets:153036 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:39521586 (39.5 MB)  TX bytes:13129921 (13.1 MB)

>> /sbin/ifconfig eth0 | grep 'inet addr'
          inet addr:172.19.90.208  Bcast:172.19.95.255  Mask:255.255.240.0

>> /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g'
172.19.90.208  Bcast:172.19.95.255  Mask:255.255.240.0

>> /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'
172.19.90.208

sed + 正则表达式
>> cat /etc/man.config | grep 'MAN'  # grep将关键字MAN所在行取出来
>> cat /etc/man.config | grep 'MAN' | sed 's/#.*$//g'  # 删除掉带批注的内容
>> cat /etc/man.config | grep 'MAN' | sed 's/#.*$//g' | sed '/^$/d'  # 删除掉空白行

例4:直接修改文件内容(危险操作):
>> sed -i 's/\.$/\!/g' regular_express.txt
# 将regular_express.txt内每一行结尾为“.”的换成“!”

>> sed -i '$a # This is a test' regular_express.txt
# 在regular_express.txt的最后一行加入“# This is a test”

参考: 《鸟哥的Linux私房菜 基础学习篇 第三版》