正则概念?
它是一门独立的学问,类似数学,很多应用都支持它,尤其是各种编程语言,在linux中各种工具,各种语言都支持,shell,grep,vim,sed,awk,python,php,perl,java。sed里用法和awk几乎一样。
表达式
算术表达式 (1+2= ,3>2)
正则表达式 reuglar expression 文档上见的最多的是regexp。是这两个单词的缩写。
在键盘上所有能敲出的符号全都可以看做是正则表达式。只不过有的只能表示自己,表示不了别的
一类 只能表示它自己
一类 能表示其他的一系列字符 (只要把这类记住,剩下的都表示它自己)元字符
基本元字符(基本正则)base regexp
扩展元字符(扩展正则)extended regexp
替换
sed -r 加-r是支持扩展正则 不加-r是支持基本正则
sed ‘s/正则/替换之后的内容/’文件名
(中间是单引号或者双引号(单引号用的多) 单引号里面是子命令,子命令就是sed可以实现的功能,比如替换,替换功能用的子命令是s 语法 sed ‘s///’ 第一个//(放的是被替换的内容/正则匹配的内容) 最终匹配的不是正则本身,是正则匹配到的内容 后面的//是放的是替换之后的内容,最后放的是文件名。
例如
[root@localhost ~]# sed ‘s/a/A’ passwd 小a换成A
[root@localhost ~]# sed 's/a/A/2' passwd 想换第几个在加个数字
[root@localhost ~]# sed 's/a/A/g' passwd 换所有 s是替换子命令 a属于正则但是a不是特殊的元字符只能表示自己,A替换后的内容 g全局,一行里所有的a 把g去掉是只匹配第一个字符
. 表示任意的单个字符(不包括换行\n)
sed 's/./A/' a.txt 每一行的第一个字符都被替换了
也可以通过管道符交给sed处理 后面就不用写文件名 cat a.txt | sed 's/../A/'
cat a.txt | sed 's/../A/' ..两个 每一行的前两个字符被替换成A
h只能表示自己 h后面不管是什么都能匹配到 会把h后面是某一个东西的组合换成A
h只能匹配它自己.可以匹配任意字符l只能匹配自己
to 换成TO t.可以换任意字符的组合
* 匹配任意多个它的前置字符或者表示它的前置字符有一个或多个 (在通配符中它表示所有)
匹配的是*前面的字符 a* 表示a有任意多个,不是a后边有多个,表示前置字符a有0个或多个。
例子:
cat a.txt | sed 's/ t*/A/' *匹配的是前置字符有一个或多个,除了它的前置字符,其他的看有没有特殊意义比如. 任意的单个字符不管t前面是什么,只要它是字符它就匹配
cat a.txt | sed 's/al*/A/'
.*所有字符 (任意的单个字符有任意个)这个所有字符和通配符的所有字符不一样,通配符里所有字符不包括没有字符,这里包括没有。
cat a.txt | sed 's/.*/A/' 每一行都换成了 A
cat a.txt | sed 's/h.*o/A/' 以h开头以o结尾,中间是任意字符
这是它的特性叫:贪婪匹配 就像贪吃蛇一样 会吞掉后面所有匹配的字符跟加不加g没关系 只要能匹配到的.*全都给匹配到 一直到后面截断的字符
cat a.txt | sed 's/h.*o /A/' 不想让他贪婪匹配 就想让他到第一个o 加个空格
cat a.txt | sed 's/h.*o /A /' 替换的后面加一个空格 单词就不是连到一块的了
把/etc/passwd的第一列全部删掉 先观察文本每一行第二列 :在基本正则没有什么特殊意义只能表示它自己,可以拿:当做截断的标记。要是不截断,它会贪婪匹配到最后一个字符。
[root@localhost ~]# sed 's/.*:x:/:x:/' /etc/passwd
^ 行首
cat a.txt | sed 's/^/A/' 在每一行的行首加一个A
cat a.txt | sed 's/^h/A/' 以h开头的行 匹配的就是h
$ 表示一行的结尾
cat a.txt | sed 's/$/A/' 每一行后面加A
cat a.txt | sed 's/u$/A/' 以u结尾的行 匹配的就是u后面加A
打印出来确实发生变化,但是源文件就没变,这种操作都是临时的,如果想让他变为永久的,
重新建一个全新的文件,重定向到其他的文件里,但是不合适,到了生产环境是直接修改原文件,想直接修改原文件加-i,原文件直接被改掉了.cat a.txt | sed -i 's/a/A/' 现在是直接改文件不能用管道的方式了,cat完了之后直接是文件的内容交给sed处理的根本不是文件,是文件内容,加个-i他就不知道了修改谁保存在哪,想让他直接修改文件把a.txt 放在后面不用管道了。sed -i 's/a/A/' a.txt 这时候就直接改了,到了公司,生产环境上要先测试 刚开始不能加-I ,测快成功了再加-i。
上面的所有正则表达式在过滤这一块都可以用,用法一模一样但是用扩展正则得加-e,不加只支持基本正则。
^$ 表示空行
sed 's/^#.*//' 把注释行删掉
sed -e 's/^#.*//' 把空行匹配一下
sed -e 's/^#.*//' -e '/^$/d' /etc/vsftpd/vsftpd.conf 定位
sed -e 's/^#.*//' /etc/vsftpd/vsftpd.conf | grep -v '^$'
[] 占位为一个字符的位置 表示匹配其中任何一个能匹配到的字符
一个[]只占位为一个字符的位置,能匹配中括号里的任意一个字符
cat a.txt | sed ‘s/a[abcdefgh]/A/’ a和其中任意一个
cat a.txt | sed ‘s/a[abcdrefgh][abcde]/A/’ a和两个[]组合 aaa
cat a.txt | sed ‘s/a[^abcdefgh]/A/’ 取反 凡是,不是括号里的都匹配 前提是前面有a
cat a.txt | sed 's/a[a-z]/A/'
[abcd]匹配其中任意一个
[^abcd]取反
[a-z]表示范围 26个字母的任意一位 范围里的东西一定要是连续的(也不能反向来 z-a) 大写的运行
[a-Z]表示52个 不能反着来 z-a
[^a-z]给a-z取反
[+-*/]错误写法 [-+*/]正确写法 匹配加减乘除 因为-表示的是范围,把-写到前面表示的就是自己不是范围或者写后面也行 [-az] [az-] -匹配的是它自己
cat a.txt | sed ‘s/-/A’ cat a.txt | sed ‘s/[abc-]/A’ ab-c a是自己b-c范围 它匹配不了-本身
[a-z]
[0-9]
[a-k]
[A-Z]
[+-*/] //错误的模式
[-+*/] //正确
[+*/-] //正确
\(\) 做分组 ()
\{\}
表示它的前置字符有3个
cat a.txt | sed 's/na\{3\}/A/'
表示它的前置字符有2到3个
cat a.txt | sed 's/na\{2,3\}/A/'
表示它的前置字符有2个以上
cat a.txt | sed 's/na\{2,\}/A/'
\ 转义字符 把有意义的变得没意义 把没意义的变得有意义
\n \t \r
\< 定位词首
# cat b.txt | sed 's/\ \> 定位词尾 # cat b.txt | sed 's/nice\>/A/' //匹配以nice结尾的单词 # cat b.txt | sed 's/\ cat a.txt | sed ‘s/(/|/’ 把小括号换成| 假如文本有个h\ello 想把这个\掉,先去匹配\ cat a | sed ‘s/\\//’ 再加一个\,它不能表示自己,加个\转义 放空就行。它本来是有意义的,基本正则,给它转义就把它原来的意义转没了。 可以换成任何符号,只要是三个,长的一样的,它会自动当成分隔符,当成///来用,这样就不会发生冲突了,/ cat a | sed 's|/||' cat a | sed 'sa/aa' 平时不要这么弄,没有特殊需求的时候,第二选择就是; 首先使用sed的时候得让它支持扩展正则,默认是不支持的,想让它支持得加-r。 grep 不加-E只支持基本正则,加了-E就支持扩展正则 () 同基本正则 写法不一样 {} 同基本正则 写法不一样 ? 表示它的前置字符有1个或0个 (单独用的情况很少,?前面怎么也得放个东西) + 表示它的前置字符有1个或多个 | a或b c或d 什么或什么 cat a | sed -r ‘s/al?/A/’ A只有第一个变了 cat a | sed -r ‘s/al+/A/’ 都变成了A cat a.txt | sed -r 's/ +/A/g' +号前面不光能放看得见的东西,空格也可以放 有时候文本,里有yes或者Yes cat a.txt | sed -r ‘s/(y|Y)es/A’ ()分组 把yes Yes整个单词都换成A,可以用小括号分组(y|Y)es。 【注意】多看书,少熬夜。扩展正则
cat a.txt | sed -r 's/e|l/A/' 想把e或者l换成A ,但是只换了一个,想换所有加g