Andy Niu �����ĵ�

Andy Niu

Andy Niu Help  1.0.0.0

变量

 原理
 
 替换
 
 提取
 
 匹配优先的问题
 

详细描述

变量说明

匹配优先的问题
1、考虑下面的情况,对于 "Tom" is short for "Thomas"
    我想提取第一个名称,即Tom
2、容易想到的办法是:
    echo \"Tom\" is short for \"Thomas\" | sed -r "s/(\")(.*)(\".*)/\2/"
    结果却是:Tom" is short for "Thomas
3、为什么?原因是 .* 是匹配优先,即贪婪模式,也就是说会尽量多吃。
4、怎么解决?使用忽略优先,也就是告诉正则表达式引擎,尽量少吃。如下:.*? 在notepad++ 编辑器中,这种方法可行。
5、但是,sed并不支持忽略优先,怎么办?
    可以尽量多吃,但是吃的内容不能包含",这种策略吃到第一个就停下来,相当于实现忽略优先,如下:
    echo \"Tom\" is short for \"Thomas\" | sed -r "s/(\")([^\"]*)(\".*)/\2/"
参见
原理
1、sed读取一行到模式空间,判断是否满足条件【地址行数或者匹配包含关键字】,满足条件,进行处理
    否则不处理。如果没有条件,都处理。
2、读取下一行之前,把模式空间的内容输出到屏幕。如果确定哪些行不显示,使用d,把这些行的模式空间删除,
    使得接下来的输出为空。如果确定哪些行要显示,其它的行不显示,使用p和-n,p相当于执行命令输出到屏幕,
    -n为安静模式,也就是说,读取下一行之前,不在输出当前行的内容。
3、sed有三层循环:
    第一层遍历所有的行
    第二层遍历一组模式/行为
    第三层遍历行为中的一组命令
参见
提取
直接使用sed,查找满足条件的一行,替换,然后打印
sed -nr '/(server-id=)/{s/(server-id=)(.*)/\2/;p}' mysql.cnf

另一种办法:使用管道,过滤出一行,替换
cat mysql.cnf|grep 'server-id='|sed -r 's/(server-id=)(.+)/\2/'
参见
替换
将 server-id=78 替换为 server-id=66,如下:
sed -r 's/(server-id=)([0-9]+)/\166/' -i mysql.cnf

注:
-r表示支持正则表达式
\166 表示 找到(server-id=)([0-9]+),两个分组,反向引用\1, 
提取出server-id=,再加上66,也就是相当于用66替换原来的数字
-i 直接修改文件

上面的替换只是,替换行中的第一个,如果要替换行中的每一个,使用
sed -r 's/(server-id=)([0-9]+)/\166/g' -i mysql.cnf
参见
Copyright (c) 2015~2016, Andy Niu @All rights reserved. By Andy Niu Edit.