目录
20.正则表达式基础
很多
*nix
的命令中,都用到了正则表达式,包括
sed
。
行的开头
( ^ )
^
匹配每一行的开头
显示以
103
开头的行
:
$ sed -n '/^103/ p' employee.txt
103,Raj Reddy,Sysadmin
只有
^
出现在正则表达式开头时,它才匹配行的开头。所以,
^N
匹配所有以
N
开头的行。
行的结尾
( $ )
$匹配行的结尾。
显示以字符
r
结尾的行:
$ sed -n '/r$/ p' employee.txt
102,Jason Smith,IT Manager
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
单个字符
( . )
元字符点
.
匹配除换行符之外的任意单个字符。
z
.
匹配单个字符
z
..
匹配两个字符
z
…
匹配三个字符
z
……以此类推
下面的例子中,模式”J 后面跟三个字符和一个空格”将被替换为”Jason 后面一个空格”。
所以,”J… “同时匹配 employee.txt 文件中的”John “和”Jane “,替换结果如下:
$ sed -n 's/J... /Jason /p' employee.txt
101,Jason Doe,CEO
105,Jason Miller,Sales Manager
匹配
0
次或多次
( * )
星号
*
匹配
0
个或多个其前面的字符。如:
1*
匹配
0
个或多个
1
先建立下面文件:
$ vim log.txt
log: input.txt
log:
log: testing resumed
log:
log:output created
假设你想查看那些包含
log
并且后面有信息的行,
log
和信息之间可能有
0
个或多个空格,
同时不想查看那些
log:
后面没有任何信息的行。
显示包含
log:
并且
log
后面有信息的行,
log
和信息之间可能有空格
:
$ sed -n '/log: *./p' log.txt
log: input.txt
log: testing resumed
log:output created
注意:
上面例子中,后面的点
.
是必需的,如果没有,
sed
只会打印所有包含
log
的行。
匹配一次或多次
( \+ )
“\+”匹配一次或多次它前面的字符,例如 空格\+ 或 “ \+”匹配至少一个或多个空格。
仍旧使用 log.txt 这个文件来作示例。
显示包含
log:
并且
log:
后面有一个或多个空格的所有行:
$ sed -n '/log: \+/ p' log.txt
log: input.txt
log: testing resumed
注意
:
这个例子既没有匹配只包含
log:
的行,也没有匹配
log:output craeted
这一行,因为
log:
后面没有空格。
零次或一次匹配
( \? )
\?匹配 0 次或一次它前面的字符。如:
$ sed -n '/log: \?/ p' log.txt
log: input.txt
log:
log: testing resumed
log:
log:output created
转义字符
( \ )
如果要在正则表达式中搜寻特殊字符(如:*,.),必需使用\来转义它们。
$ sed -n '/127\.0\.0\.1/ p' /etc/hosts
127.0.0.1 localhost
字符集
( [0-9] )
字符集匹配方括号中出现的任意一个字符。
匹配包含
2
、
3
或者
4
的行
:
$ sed -n '/[234]/ p' employee.txt
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
在方括号中,可以使用连接符-指定一个字符范围。如[0123456789]可以用[0-9]表示,字母可
以用[a-z],[A-Z]表示,等等。
匹配包含
2
、
3
或者
4
的行
(
另一种方式
):
$ sed -n '/[2-4]/ p' employee.txt
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
21.其他正则表达式
或操作符
( | )
管道符号
|
用来匹配两边任意一个子表达式。子表达式
1|
子表达式
2
匹配子表达式
1
或者子
表达式
2
打印包含
101
或者包含
102
的行:
$ sed -n '/101\|102/ p' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
需要注意,| 需要用\转义。
打印包含数字 2~3 或者包含 105 的行:
$ sed -n '/[2-3]\|105/ p' employee.txt
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
105,Jane Miller,Sales Manager
精确匹配
m
次
( {m} )
正则表达式后面跟上{m}标明精确匹配该正则 m 次。
请先建立如下文件:
$ vi numbers.txt
1
12
123
1234
12345
123456
打印包含任意数字的行
(
这个命令将打印所有行
):
$ sed -n '/[0-9]/ p' numbers.txt
1
12
123
1234
12345
123456
打印包含
5
个数字的行
:
$ sed -n '/^[0-9]\{5\}$/ p' numbers.txt
12345
注意这里一定要有
s
开头和结尾符号,即
^
和
$,
并且
{
和
}
都要用
\
转义
匹配
m
至
n
次
( {m,n} ):
正则表达式后面跟上
{m,n}
表明精确匹配该正则至少
m
,最多
n
次。
m
和
n
不能是负数,并
且要小于
255.
打印由
3
至
5
个数字组成的行:
$ sed -n '/^[0-9]\{3,5\}$/ p' numbers.txt
123
1234
12345
正则表达式后面跟上
{m,}
表明精确匹配该正则至少
m
,最多不限。
(
同样,如果是
{,n}
表明最
多匹配
n
次,最少一次
)
。
字符边界
( \b )
\b
用来匹配单词开头
(\bxx)
或结尾
(xx\b)
的任意字符,因此
\bthe\b
将匹配
the,
但不匹配
they.
\bthe
将匹配
the
或
they.
请先建立如下文件
:
$ cat words.txt
word matching using: the
word matching using: thethe
word matching using: they
匹配包含 the 作为整个单词的行:
$ sed -n '/\bthe\b/ p' words.txt
word matching using: the
注意:如果没有后面那个
\b,
将匹配所有行。
匹配所有以 the 开头的单词:
$ sed -n '/\bthe/ p' words.txt
word matching using: the
word matching using: thethe
word matching using: they
回溯引用 ( \n )
使用回溯引用,可以给正则表达式分组,以便在后面引用它们。
只匹配重复 the 两次的行:
$ sed -n '/\(the\)\1/ p' words.txt
word matching using: thethe
同理,
”\([0-9]\)\1”
匹配连续两个相同的数字,如
11,22,33 …..
22.在 sed 替换中使用正则表达式
下面是一些使用正则表达式进行替换的例子。
把 employee.txt 中每行最后两个字符替换为”,Not Defined”:
$ sed -n 's/..$/,Not Defined/ p' employee.txt
101,John Doe,C
,Not Defined
102,Jason Smith,IT Manag
,Not Defined
103,Raj Reddy,Sysadm
,Not Defined
104,Anand Ram,Develop
,Not Defined
105,Jane Miller,Sales Manag
,Not Defined
删除以
Manager
开头的行的后面的所有内容
:
$ sed 's/^Manager.*//' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
这个示例好像有点问题啊,我觉得应该是
sed ‘s/^Manager.*/Manager/’
删除所有以
#
开头的行:
$ sed -e 's/#.*// ; /^$/ d' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
我觉得用
sed ‘/^#/ d’
更好
建立下面的 test.html 文件:
$ vim test.html
<html><body><h1>Hello World!</h1></body></html>
清除
test.html
文件中的所有
HTML
标签
:
$ sed 's/<[^>]*>//g' test.html
Hello World!
删除所有注释行和空行
:
$ sed -e 's/#.*// ; /^$/ d' /etc/profile
只删除注释行,保留空行
:
sed '/#.*/ d' /etc/profile
使用
sed
可以把
DOS
的换行符
(CR/LF)
替换为
Unix
格式。当把
DOS
格式的文件拷到
Unix
上,
你会发现,每行结尾都有
\r\n .
使用
sed
把
DOS
格式的文件转换为
Unix
格式
:
sed ‘s/.$//’ filename
资料来源于《SedandAwk101Hacks》,大家有兴趣可以买一本,也可以关注我,我更新完它。
曾经,我花费大半月将它们跑完,现在啥都忘了,还是要常用。
只为学习交流,不为获利,侵权联系立删。