郑仁培 發表於 2022-8-9 16:01:26

Linux行处理工具之grep 正则表达式详解

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">正则表达式在grep应用以及差别</a></li><li><a href="#_label1">匹配案例</a></li><li><a href="#_label2">fgrep</a></li><li><a href="#_label3">总结</a></li></ul></div><blockquote><p>之前我们学习了<code>linux grep</code>的基本操作,以及提及了<code>linux grep</code>的孪生兄弟<code>egrep 和 fgrep</code>,这次我们来看下。</p></blockquote>
<p>在介绍正则表达式之前,我们先来尝试一下,假如有如下文本。</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531203.png?20227915588" /></p>
<p>我们想获取空行,应该如何来写呢?</p>
<p>命令:</p>
<div class="jb51code"><pre class="brush:bash;">grep ^$ test1 -n</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531204.png" /></p>
<p>通过上述例子,我们使用正则表达式<code>^$</code>已经成功拿到了第四行数据,那么,这究竟如何解呢,我们细看博文。</p>
<p class="maodian"><a name="_label0"></a></p><h3>正则表达式在grep应用以及差别</h3>
<p><code>grep</code>表达式有三种不同的版本,分别为<code>basic</code>(<code>BRE</code>) 、<code>extended</code>(<code>ERE</code>) 以及 <code>perl</code>(<code>PCRE</code>) ,我们<code>grep</code>默认支持的是<code>BRE</code>,而<code>ERE</code>是<code>egrep</code>支持的,或者说是<code>grep -E</code>支持的, 而<code>PCRE</code>则是<code>grep -P</code>支持的,那么这三者究竟有啥区别呢?</p>
<table><tbody><tr><th>&nbsp;</th><th>BRE</th><th>ERE</th><th>PCRE</th></tr><tr><td>任意字符</td><td>.</td><td>.</td><td>.</td></tr><tr><td>前一个字符0次或者出现1次</td><td>?</td><td>?</td><td>?</td></tr><tr><td>前一个字符出现0次或无数次</td><td>*</td><td>*</td><td>*</td></tr><tr><td>前一个字符出现一个或者更多</td><td>+</td><td>+</td><td>+</td></tr><tr><td>字符集</td><td>[...]</td><td>[...]</td><td>[...]</td></tr><tr><td>字符集取反</td><td>[^...]</td><td>[^...]</td><td>[^...]</td></tr><tr><td>匹配前面字符出现的n次</td><td>{n}</td><td>{n}</td><td>{n}</td></tr><tr><td>匹配前面字符出现的n次以上</td><td>{n,}</td><td>{n,}</td><td>{n,}</td></tr><tr><td>匹配前面字符出现的n次到m次</td><td>{n,m}</td><td>{n,m}</td><td>{n,m}</td></tr><tr><td>开头</td></tr><tr><td>结尾</td><td>$</td><td>$</td><td>$</td></tr><tr><td>多表达式连接</td><td>|</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>单词</td><td>\w</td><td>\w</td><td>\w 或者 [[:word:]]</td></tr><tr><td>字母大写/小写</td><td>[[:upper:]]/[[:lower:]]</td><td>[[:upper:]]/[[:lower:]]</td><td>[[:upper:]]/[[:lower:]]</td></tr><tr><td>非单词</td><td>&nbsp;</td><td>&nbsp;</td><td>\W</td></tr><tr><td>空白字符</td><td>\s 或者 [[:space:]]</td><td>\s 或者 [[:space:]]</td><td>&nbsp;</td></tr><tr><td>非空白字符</td><td>[^[:space:]]</td><td>[^[:space:]]</td><td>\S</td></tr><tr><td>数字</td><td>\d 或者 [[:digit:]]</td><td>[[:digit:]]</td><td>[[:digit:]]</td></tr><tr><td>非数字</td><td>\D</td><td>[^[:digit:]]</td><td>[^[:digit:]]</td></tr></tbody></table>
<p>那么如何进行切换呢? 如上面所示,我们来看下。</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531205.png" /></p>
<p>如上所述,若我们需要连接多个匹配项,在<code>BRE(grep)</code>中则是<code>|</code>,而在<code>ERE(egrep)</code>和<code>PCRE(grep -P)</code>中则是<code>|</code>,所以我们可以顺利获取出结果,更多匹配项如上所述</p>
<p class="maodian"><a name="_label1"></a></p><h3>匹配案例</h3>
<p>匹配电话号码</p>
<p>若电话号码为<code>xxx-xxxx-xxxx</code>类型的,如何进行匹配呢? 我们可以使用<code>&#39;{3}-{4}-{4}&#39;</code>进行匹配。</p>
<p>例如:</p>
<p>命令:</p>
<div class="jb51code"><pre class="brush:bash;">echo "telphone: 180-1234-5678" | grep'{3}-{4}-{4}' -o</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531206.png" /></p>
<p>同样的,该方法还可以用来匹配其<code>ip</code>地址,正则: <code>{0,3}.{0,3}.{0,3}.{0,3}</code></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531207.png" /></p>
<p>匹配空行</p>
<p>若我们想匹配空行,则可以使用<code>^$</code>进行匹配,即: 开头就是结尾。</p>
<p>例如:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531208.png" /></p>
<p>如上命令,我们顺利取出了 第3、5、6行数据</p>
<p>匹配所有字母</p>
<p>命令:</p>
<div class="jb51code"><pre class="brush:bash;">echo 'Ac123e23dddwQW21' | grep "[[:upper:]]|[[:lower:]]" -o</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531209.png" /></p>
<p>取出<code>redis</code>在使用的配置文件</p>
<p>我们知道<code>redis</code>服务器是以<code>#</code>来注释的,我们可以利用<code>grep</code>或者<code>egrep</code>来过滤掉注释和空格,例如:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531210.png" /></p>
<p class="maodian"><a name="_label2"></a></p><h3>fgrep</h3>
<p><code>fgrep</code>最为简单,它不会启用正则表达式,而是按照字符来进行搜索,什么意思呢? 我们举个小案例就清楚了,</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/202289155531211.png" /></p>
<p>它不会进行任何正则匹配,所以可以直接使用搜索选就成,不用考虑转移啥的。</p>
<p class="maodian"><a name="_label3"></a></p><h3>总结</h3>
<p>我们一般将<code>BRE</code>称之为 基本正则表达式、<code>ERE</code>称之为 扩展正则表达式 而 <code>PCRE</code>称之为<code>Perl</code>兼容的正则表达式,如上正则表达式不是<code>grep</code>工具所实现的,而是单独的一套表达式,有很多语言在使用中,例如 <code>sed</code>默认正则表达式是 <code>BRE</code>, 而我们之前所学习的<code>awk</code>使用的正则表达式则是<code>ERE</code>,是不是感觉知识被串联起来了呢,好巧,我也是,怎么样,快来动手试验一下吧。</p>
頁: [1]
查看完整版本: Linux行处理工具之grep 正则表达式详解