在学习正则表达式以及文档内容查找三剑客-grep sed awk的过程中,我们难免会遇到查找特殊的字符,包括正则表达式中也有\d \w等包含转义符号的集合,作为一名初学者,在写这方面的内容的过程中遇到了转义混乱的问题,故在此写一些自己的感悟与大家分享,欢迎批评指正。
引号
首先对两种引号进行区分
1、单引号:
可以说是所见即所得:单引号里面看到的是什么就会输出什么。被单引号括起的内容不管是常量还是变量者不会发生替换。
2、双引号:
把双引号内的内容输出出来,如果内容中有命令、变量等,会先把变量、命令会先解析出结果,然后在输出最终内容来;被双引号括起的内容常量还是常量,变量则会发生替换,替换成变量内容。
3、不加引号:
不会将含有空格的字符串视为一个整体输出, 如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容来,如果字符串中带有空格等特殊字符,则不能完整的输出,需要改加双引号,一般连续的字符串,数字,路径等可以用。
正则表达式认可的特殊符号
. * [ ] ^ $ { } \ + ? | ( )
字符串认可的特殊符号
\n \a 等
传递的方法
通过前面的了解,我知道了正则表达式和字符串所认可的特殊字符,那么当我们写grep等的命令的时候,应该怎么写字符串的格式呢?
我认为是这种形式,grep和sed以及awk都是把字符串当成参数输入到函数内部作为处理的,所以我们可以认为是两步:
1.字符串脱去引号保存到内存地址中
2.函数对内存保存的内容以正则表达式的理解方式进行处理
下面以一个例子来说明:
注:例子引用了其他CSDN博主的内容,因为整理的时候删了来源,所以找不到了,在此深表感谢。
~/Documents/books/linux/test$:cat 1.txt
[:50]
~/Documents/books/linux/test$:cat test.sh
#!/bin/bash
oldstr="[:50]"
newstr="[50:100]"
cat 1.txt | sed -n 's/$oldstr/$newstr/p'
但是却没有输出,这个情况是由于单引号不进行双引号的处理,直接将$符号当成字符输入了,单引号不进行双引号的转义和变量引用。
那么换成
#!/bin/bash
oldstr="[:50]"
newstr="[50:100]"
cat 1.txt | sed -n "s/$oldstr/$newstr/p"
执行后发现得到的结果
~/Documents/books/linux/test$:./test.sh
[[50:100]50]
而不是我们想要得到的:
[50:100]
这就是因为s/ /之间匹配的是正则表达式,作为字符串而言,"[:50]"传递到内存位置是很正常的,没有问题,但是在正则表达式处理的时候,认为[:50]的含义是:或者5或者0,然后把第一个:替换掉了,把后面的字符串放进去。
正确写法:
#!/bin/bash
oldstr="\[:50\]"
newstr="[50:100]"
cat 1.txt | sed -n "s/$oldstr/$newstr/g;p"
通过这个例子,是不是明白了很多。实际上就是一步步的进行这个过程,每一步都保证传递到下一个步骤的起始就好了,就像上面这个"[:50]" ,我们写成
"\\[:50\\]"
也是可以的,只不过是双引号那一步进行了一次转义,对于存储到内存位置要被正则表达式处理的东西没有影响。