grep 正则表达式用引号括起来和元字符加反斜杠转义的测试
grep 正则表达式用引号括起来和元字符加反斜杠转义的测试
实验在 grep 命令中的表达式:不加引号,加单引号,加双引号的区别,以及部分元字符前加与不加 `\’ 进行转义的区别。实验环境为“实验楼( http://www.shiyanlou.com/ )上的 CentOS 6 ,GNU grep 2.6.3。
1、测试不把 grep 的表达式加上引号:
[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 backslashed
versions `\?’, `\+’, `\{’, `\|’, `\(’, 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教程网
grep 正则表达式用引号括起来和元字符加反斜杠转义的测试的更多相关文章
- js进阶正则表达式7点数字字母空格(w d s)(小写表原意,大写表反义)(特殊字符要加反斜杠:var reg22=/\W/g)
js进阶正则表达式7点数字字母空格(w d s)(小写表原意,大写表反义)(特殊字符要加反斜杠:var reg22=/\W/g) 一.总结 1.w d s,word digital space 2.特 ...
- 正则表达式,字符串中需要两个反斜杠“\\d”
这个正则表达式为什么会有两个反斜杠? "^.*?\\.(jpg|png|bmp|gif)$"上面这个正则表达式为什么有两个反斜杠呢?反斜杠点\.就能表示点.了,为什么还要在\.前面 ...
- 每日linux命令学习-引用符号(反斜杠\,单引号'',双引号"")
引用符号在解析器中保护特殊元字符和参数扩展,其使用方法有3种:反斜杠(\),单引号(’‘),双引号(“”). 单引号和双引号必须匹配使用,均可在解析器中保护特殊元字符和通配符,但是单引号(硬转义)主要 ...
- python 正则表达式中反斜杠(\)的麻烦和陷阱
这里是一点小心得:由于下面两个原因,在正则表达式中使用反斜杠就会产生了一个双重转换的问题. (1).python自身处理字符串时,反斜杠是用于转义字符 (2).正则表达式也使用反斜杠来转义字符 ...
- 关于Python中正则表达式的反斜杠问题
之前总是搞不明白正则表达式中的反斜杠的问题.今天经过查阅资料终于搞明白了. 其中最重要的一点就是Python自己的字符串中定义的反斜杠也是转义字符,而正则表达式中的反斜杠也是转义字符,所以正则表达式中 ...
- Unix Shell中单引号、双引号字符、反斜杠、反引号的使用[转]
在执行shell脚本的时候,shell将会对脚本中的行进行解释,然后执行:对于一些特殊处理的句子,我们可以使用引号或者反斜线来避免shell解释执行之.如下,当在命令行中输入:echo *child. ...
- JS_正则表达式_使用字符串创建的正则表达式_反斜杠也需要添加转义符
备注: 使用字符串创建的正则表达式:"\"也需要加转义符: var reg1=new RegExp("\\w+"); 这和 直接使用:var r ...
- PHP在引号前面添加反斜杠的原因及PHP去除反斜杠的办法
昨天用PHP做了个读写html文档的小程序,本地测试正常但是传到网站后发现,提交内容保存的时候会自动在双引号前面增加一个反斜杠“\”,而且每保存一次增加一个反斜杠,很是郁闷. 当然做这个只是为了参加电 ...
- grep正则表达式后面的单引号和双引号的区别
单引号''是全引用,被单引号括起的内容不管是常量还是变量者不会发生替换:双引号""是部分引用,被双引号括起的内容常量还是常量,变量则会发生替换,替换成变量内容! 一般常量用单引号' ...
随机推荐
- linux-2.6.38 input子系统(用输入子系统实现按键操作)
一.设备驱动程序 在上一篇随笔中已经分析,linux输入子系统分为设备驱动层.核心层和事件层.要利用linux内核中自带的输入子系统实现一个某个设备的操作,我们一般只需要完成驱动层的程序即可,核心层和 ...
- MySQL中DATA类型数据和DATATIME类型数据的比较
在网上大题查了下这个问题,网上有的人说可以直接比较,并给出了测试用例,也有的人说不能比较,于是我自己尝试了一下,实际测试是可以的,不过,当传入DATA类型时间与DATATIME类型时间进行比较的时候, ...
- Training #2 cell battle (BFS)
Constraints: 1 <= R, C <= 500 1 <= T <= 5 Sample Input: 5 3 5 ##### a...b ##### 3 4 #### ...
- 如何在SpringBoot的 过滤器之中注入Bean对象
我建立一个全局拦截器,此拦截器主要用于拦截APP用户登录和请求API时候,必须加密,我把它命名为SecurityFilter,它继承了Filter,web应用启动的顺序是:listener->f ...
- Vue入门(四)——Axios向SpringMVC传数据
在实际业务需求中,经常会出现前台传表单或者对象到后台,后台Handler接受并转换成对应的POJO以供业务代码使用 此时在SpringMVC框架中就要用到@RequestBody注解,该注解用于将请求 ...
- 使用Ajax中get请求发送Token时踩的那些坑
在使用惯了各种牛X的插件以后,在使用原生组件写一些小东西的时候总是有踩不完的坑! 今天就来说一说我使用原生ajax请求时踩得坑: 下面是我的代码: var xmlhttp; if (window.XM ...
- 在maven项目中如何引入另外一个项目(转)
原文链接:https://blog.csdn.net/jianfpeng241241/article/details/52654352 1 在Myeclipse中准备两个maven demo. , ...
- HDU 5734 Acperience ( 数学公式推导、一元二次方程 )
题目链接 题意 : 给出 n 维向量 W.要你构造一个 n 维向量 B = ( b1.b2.b3 ..... ) ( bi ∈ { +1, -1 } ) .然后求出对于一个常数 α > 0 使得 ...
- 【CUDA 基础】5.1 CUDA共享内存概述
title: [CUDA 基础]5.1 CUDA共享内存概述 categories: - CUDA - Freshman tags: - CUDA共享内存模型 - CUDA共享内存分配 - CUDA共 ...
- 7.19T3
小 X 的图 题目背景及题意 小 X 有一张图,有 n 个点(从 0 开始编号),一开始图里并没有 边,他有时候会向其中添加一条双向边(x 到 y).小 X 会时不时想知 道某两个点是否联通,如果连通 ...