grep 正则表达式用引号括起来和元字符加反斜杠转义的测试
2015-03-27 10:02
441 查看
grep 正则表达式用引号括起来和元字符加反斜杠转义的测试实验在 grep 命令中的表达式:不加引号,加单引号,加双引号的区别,以及部分元字符前加与不加 `\’ 进行转义的区别。实验环境为“实验楼( http://www.shiyanlou.com/ )上的 CentOS 6 ,GNU grep 2.6.3。1、测试不把 grep 的表达式加上引号:
可见,如果 grep 的表达式不加引号,碰到通配符等就会因为 bash 的扩展功能,而先把表达式进行扩展,扩展的结果再送入表达式进行grep 的命令执行。2、下面测试把 grep 的表达式加上单引号括起来的情况:
可见,grep 表达式用单引号括起来就避免了 bash 的预先扩展。但是,要注意,bash -x 的展开功能的展开顺序不是固定的,如上,有时先展开 ls ./*,有时先展开 grep ‘hell*’(因为是加的单引号,所以展开后保持不变。)。但是,展开后的执行是先执行 ls ./* ,结果再传给 grep ‘hell*’ 执行的。3、下面测试把 grep 的表达式加双引号括起来的情况:
可以看出,grep 的表达式加上双引号,可以避免一部分 bash 扩展功能,如 ls ./* | grep “hell*” 中 grep 表达式中的 *;但是不能避免变量扩展,如可以扩展:a=”he”; ls ./* | grep “${a}ll*”。另外,在测试 bash -x -c ‘a=”he”; ls ./* | grep ‘${a}ll*” 和 a=he; ls ./* | grep ‘${a}ll*’ 时,我们看见了不一样的结果,具体原因不明,有可能是 bash -c 的功能对’${a}ll*’作了一些修改?另外,虽然暂时看来在 grep 中的表达式用双引号括起来似乎可以利用它扩展变量的功能把 grep 的正则表达式弄成变量,但是,这个功能有没有其它的副作用呢?目前没有查找到相关的文档依据,所以保险的做法是:在 grep 的正则表达式中只用单引号括起来。这种做法也是 grep 的 info 文档中的例子所采用的。4、实验一下 grep 使用基本正则表达式时,部分元字符必须加上转义 \ 的情况:在 info grep 的菜单:* Regluar Expressions:: ->Basic vs Extended:: 中写道: 3.6 Basic vs Extended Regular Expressions=========================================In basic regular expressions the meta-characters `?’, `+’, `{’, `|’,`(’, and `)’ lose their special meaning; instead use the backslashedversions `\?’, `\+’, `\{’, `\|’, `\(’, and `\)’.所以,必须在 grep 的正则表达式中使用 \ 以使这些字符的作用生效。如下(继续使用上面的测试环境):
5、结论:在使用 grep 时,正则表达式一定要用单引号括起来,否则可能因为 shell 执行环境的预先展开功能导致错误;在基本正则表达式(grep 默认为基本正则表达式)中的元字符 `?’, `+’, `{’, `|’,`(’, `)’ 前面一定要加上 `\’ 进行转义。另外,注意区分通配符`?’, `*’, `[]‘ 与正则表达式中相应字符的含义和用法。欢迎交流探讨,若有错漏,敬请批评与斧正。谢谢。本文来自:Linux教程网
[root@d9a69d7b11ac test]#mkdir test; cd test; touch hello [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep hell*" + ls ./hello + grep hello ./hello [root@d9a69d7b11ac test]# touch hello2 [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep hell*" + ls ./hello ./hello2 + grep hello hello2 [root@d9a69d7b11ac test]# echo "hello3" > hello2 [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep hell*" + ls ./hello ./hello2 + grep hello hello2 hello3 [root@d9a69d7b11ac test]#
可见,如果 grep 的表达式不加引号,碰到通配符等就会因为 bash 的扩展功能,而先把表达式进行扩展,扩展的结果再送入表达式进行grep 的命令执行。2、下面测试把 grep 的表达式加上单引号括起来的情况:
[root@d9a69d7b11ac test]# rm hello2 rm: remove regular empty file `hello2'? y [root@d9a69d7b11ac test]# ls hello [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep 'hell*'" + grep 'hell*' + ls ./hello ./hello [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep 'hell*'" + ls ./hello + grep 'hell*' ./hello [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep 'hell*'" + grep 'hell*' + ls ./hello ./hello [root@d9a69d7b11ac test]# touch hello2 [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep 'hell*'" + ls ./hello ./hello2 + grep 'hell*' ./hello ./hello2 [root@d9a69d7b11ac test]# echo "hello3" > hello2 [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep 'hell*'" + ls ./hello ./hello2 + grep 'hell*' ./hello ./hello2 [root@d9a69d7b11ac test]#
可见,grep 表达式用单引号括起来就避免了 bash 的预先扩展。但是,要注意,bash -x 的展开功能的展开顺序不是固定的,如上,有时先展开 ls ./*,有时先展开 grep ‘hell*’(因为是加的单引号,所以展开后保持不变。)。但是,展开后的执行是先执行 ls ./* ,结果再传给 grep ‘hell*’ 执行的。3、下面测试把 grep 的表达式加双引号括起来的情况:
[root@d9a69d7b11ac test]# rm hello2 rm: remove regular empty file `hello2'? y [root@d9a69d7b11ac test]# ls hello [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep "hell*"" + ls ./hello + grep hello ./hello [root@d9a69d7b11ac test]# bash -x -c 'ls ./* | grep "hell*"' + ls ./hello + grep 'hell*' ./hello [root@d9a69d7b11ac test]# touch hello2 [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep "hell*"" + ls ./hello ./hello2 + grep hello hello2 [root@d9a69d7b11ac test]# bash -x -c 'ls ./* | grep "hell*"' + ls ./hello ./hello2 + grep 'hell*' ./hello ./hello2 [root@d9a69d7b11ac test]# ls ./* | grep "hell*" ./hello ./hello2 [root@d9a69d7b11ac test]# echo "hello3" > hello2 [root@d9a69d7b11ac test]# bash -x -c "ls ./* | grep "hell*"" + grep hello hello2 + ls ./hello ./hello2 hello3 [root@d9a69d7b11ac test]# bash -x -c 'ls ./* | grep "hell*"' + ls ./hello ./hello2 + grep 'hell*' ./hello ./hello2 [root@d9a69d7b11ac test]# ls ./* | grep "hell*" ./hello ./hello2 [root@d9a69d7b11ac test]# bash -x -c 'a="he"; ls ./* | grep "${a}ll*"' + a=he + ls ./hello ./hello2 + grep 'hell*' ./hello ./hello2 [root@d9a69d7b11ac test]# bash -x -c 'a="he"; ls ./* | grep '${a}ll*'' + a=he + ls ./hello ./hello2 + grep 'll*' ./hello ./hello2 ./hello2 [root@d9a69d7b11ac test]# a=he; ls ./* | grep '${a}ll*' [root@d9a69d7b11ac test]# a=he; ls ./* | grep "${a}ll*" ./hello ./hello2 [root@d9a69d7b11ac test]# bash -x -c 'a="he"; ls ./* | grep ${a}ll*' + a=he + ls ./hello ./hello2 + grep hello hello2 hello3 [root@d9a69d7b11ac test]# a="he"; ls ./* | grep ${a}ll* hello3 [root@d9a69d7b11ac test]#
可以看出,grep 的表达式加上双引号,可以避免一部分 bash 扩展功能,如 ls ./* | grep “hell*” 中 grep 表达式中的 *;但是不能避免变量扩展,如可以扩展:a=”he”; ls ./* | grep “${a}ll*”。另外,在测试 bash -x -c ‘a=”he”; ls ./* | grep ‘${a}ll*” 和 a=he; ls ./* | grep ‘${a}ll*’ 时,我们看见了不一样的结果,具体原因不明,有可能是 bash -c 的功能对’${a}ll*’作了一些修改?另外,虽然暂时看来在 grep 中的表达式用双引号括起来似乎可以利用它扩展变量的功能把 grep 的正则表达式弄成变量,但是,这个功能有没有其它的副作用呢?目前没有查找到相关的文档依据,所以保险的做法是:在 grep 的正则表达式中只用单引号括起来。这种做法也是 grep 的 info 文档中的例子所采用的。4、实验一下 grep 使用基本正则表达式时,部分元字符必须加上转义 \ 的情况:在 info grep 的菜单:* Regluar Expressions:: ->Basic vs Extended:: 中写道: 3.6 Basic vs Extended Regular Expressions=========================================In basic regular expressions the meta-characters `?’, `+’, `{’, `|’,`(’, and `)’ lose their special meaning; instead use the backslashedversions `\?’, `\+’, `\{’, `\|’, `\(’, and `\)’.所以,必须在 grep 的正则表达式中使用 \ 以使这些字符的作用生效。如下(继续使用上面的测试环境):
[root@e16578371323 test]# ls hello hello2 [root@e16578371323 test]# ls ./* | grep 'hell?' [root@e16578371323 test]# ls ./* | grep 'hell\?' ./hello ./hello2 [root@e16578371323 test]# ls ./* | grep 'hel{2}' [root@e16578371323 test]# ls ./* | grep 'hel\{2\}' ./hello ./hello2 [root@e16578371323 test]#
5、结论:在使用 grep 时,正则表达式一定要用单引号括起来,否则可能因为 shell 执行环境的预先展开功能导致错误;在基本正则表达式(grep 默认为基本正则表达式)中的元字符 `?’, `+’, `{’, `|’,`(’, `)’ 前面一定要加上 `\’ 进行转义。另外,注意区分通配符`?’, `*’, `[]‘ 与正则表达式中相应字符的含义和用法。欢迎交流探讨,若有错漏,敬请批评与斧正。谢谢。本文来自:Linux教程网
相关文章推荐
- sas9正则表达式测试(对字符串进行字符替换)
- java 的转义字符,在正则表达式中应用
- java 正则表达式,特殊字符转义
- 正则表达式中问号等特殊字符的转义
- 正则表达式特殊字符转义
- java 的转义字符,在正则表达式中应用
- 正则表达式中问号等特殊字符的转义
- 正则表达式中的 grep程序支持的meta字符plus和POSIX
- 正则表达式中问号等特殊字符的转义
- grep 正则表达式选项要记得转义(转)
- NET正则表达式问号等特殊字符的转义与按组名分组引用
- 正则表达式中问号等特殊字符的转义
- c#正则表达式中特殊字符转义
- 正则表达式中特殊字符的转义
- C#中正则表达式无法转义的字符
- 正则表达式需要转义的字符
- 正则表达式--字符转义
- 正则表达式中问号等特殊字符的转义【转】
- 正则表达式中的 grep程序支持的meta字符plus和POSIX
- C#正则表达式的特定字符或转义序列