我是靠谱客的博主 纯真冬日,这篇文章主要介绍细读shell-6,现在分享给大家,希望可以做个参考。

 在认识了 char. set 这个概念后, 然后再让我们多认识几个 RE 中常见的 meta 字符: 

 

- 锚点(anchor) 

用以标识 RE 于句子中的位置所在. 常见有: 

^: 表示句首. 如 ^abc 表示以 abc 开首的句子. 

$: 表示句尾. 如 abc$ 表示以 abc 结尾的句子. 

<: 表示词首. 如 <abc 表示以 abc 开首的词. 

>: 表示词尾. 如 abc> 表示以 abc 结尾的词. 

 

- 修饰字符(modifier) 

独立表示时本身不具意义, 专门用以修改前一个 char. set 的出现次数. 常见有: 

*: 表示前一个 char. set 的出现次数为 0 或多次. 如 ab*c 表示 a 与 c 之间可有 0 或多

个 b 存在. 

?: 表示前一个 char. set 的出现次数为 0 或 1 次. 如 ab?c 表示 a 与 c 之间可有 0 或

1 个 b 存在. 

+: 表示前一个 char. set 的出现次数为 1 或多次. 如 ab+c 表示 a 与 c 之间可有 1 或

多个 b 存在. 

{n}: 表示前一个 char. set 的出现次数必须为 n 次. 如 ab{3,}c 表示 a 与 c 之间必须

有 3 个 b 存在.{n,}: 表示前一个 char. set 的出现次数至少为 n 次. 如 ab{3,}c 表示

a 与 c 之间至少有 3 个 b 存在. 

{n,m}: 表示前一个 char. set 的出现次数为 n 到 m 次. 如 ab{3,5}c 表示 a 与 c 之

间有 3 到 5 个 b 存在. 

 

然而, 当我们在识别 modifier 时, 却很容易忽略"边界(boundary)"字符的重要性. 

以刚提到的 ab{3,5}c 为例, 这里的 a 与 c 就是边界字符了. 

若没有边界字符的帮忙, 我们很容以作出错误的解读. 

比方说: 我们用 ab{3,5} 这个 RE (少了 c 这个边界字符)可以抓到 abbbbbbbbbbc (a 后

有 10 个 b )这串字吗? 

从刚才的 modifier 我们一般会认为我们要的 b 是 3 到 5 个, 若超出了此范围, 就不是我

们要表达的. 

因此, 我们或会很轻率的认为这个 RE 抓不到结果... 

然而答案却是可以的! 为甚么呢? 

让我们重新解读 ab{3,5} 这个 RE 看看: 

我们要表达的是 a 后接 3 到 5 个 b 即可, 但 3 到 5 个 b 后面我们却没规定是甚么, 

因此在 RE 后面可以是任意的文字, 当然包括 b 也可以啦! (明白了吗?) 

同样的, 我们用 b{3,5}c 也同样可以抓到 abbbbbbbbbbc 这串字的. 

但我们若使用 ab{3,5}c 这样的 RE 时, 由于同时有 a 与 c 这两个边界字符, 那就截然不

同了! 

 

有空再思考一下, 为何我们用下面这些 RE 都可抓到 abc 这串字呢? 

x* 

ax*, abx*, ax*b 

abcx*, abx*c, ax*bc 

bx*c, bcx*, x*bc 

...(还有更多...) 

但, 若我们在这些 RE 前后分别加一个 ^ 与 $ 这样的 anchor, 那又如何呢? 

 

刚学 RE 时, 只要能掌握上面这些基本的 meta 大盖就可以入门了. 

一如前述, RE 是一种规范化的文字表达方式, 主要用于某些文字处理工具之间, 

如 grep, perl, vi, awk, sed, 等等. 常用以表示一段连续的字符串, 捕获之或替换之. 

然而, 每种工具对 RE 表达式的具体解读或有一些细微差异, 不过, 基本原则还是一致的. 

只要能掌握 RE 的基本原理, 那就一理通百理明了, 只是在实作时稍加变通即可. 

 

比方以 grep 来说, 在 Linux 上你可找到 grep, egrep, fgrep 这几个程序, 其差异大致如

下: 

 

* grep: 

传统的 grep 程序, 在没有参数的情况下, 只输出符合 RE 字符串之句子. 常见参数如下: 

-v: 逆反模示, 只输出"不含" RE 字符串之句子. 

-r: 递归模式, 可同时处理所有层级子目录里的文件. 

-q: 静默模式, 不输出任何结果(stderr 除外. 常用以获取 return value, 符合为 true, 否则

为 false .) 

-i: 忽略大小写. 

-w: 整词比对, 类似 <word> . 

-n: 同时输出行号. 

-c: 只输出符合比对的行数. 

-l: 只输出符合比对的文件名称. 

-o: 只输出符合 RE 的字符串. (gnu 新版独有, 不见得所有版本都支持.) 

-E: 切换为 egrep . 

 

* egrep: 

为 grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作. 比方说: 

- grep 之下不支持 ? 与 + 这两种 modifier, 但 egrep 则可. 

- grep 不支持 a|b 或 (abc|xyz) 这类"或一"比对, 但 egrep 则可. 

- grep 在处理 {n,m} 时, 需用 { 与 } 处理, 但 egrep 则不需. 

诸如此类的... 我个人会建议能用 egrep 就不用 grep 啦...  ^_^ 

 

* fgrep: 

不作 RE 处理, 表达式仅作一般字符串处理, 所有 meta 均失去功能. 

 好了... 

关于 RE 的入门, 我暂时就介绍到这里. 

虽然写得有点乱, 且有些观念也不很精确, 不过, 姑且算是对大家有一个交差吧.... ^_^ 

若这两天还有时间的话, 我再举些范例来分析一下, 以助大家更好的理解. 

假如更有可能的话, 也顺道为大家介绍一下 sed 这个工具. 

(啊, 这次我不敢作保证了哦... ^_^ )

 

 

 

---------------- 

(顺道一提: eval ) 

 

讲到 command line 的重组特性, 真的需要我们好好的加以理解的. 

如此便能抽丝剥襺的一层层的将正个 command line 分析得一清二楚, 而不至于含糊. 

假如这个重组特性理解下来来, 那么, 接下来我们介绍一个好玩的命令 --- eval . 

 

我们在不少变量替换的过程中, 常碰到所谓的复式变量的问题, 如:  

代码:

a=1 

A1=abc

 

我们都知道 echo $A1 就可得到 abc 这个结果. 

然而, 我们能否用 $A$a 来取代 $A1 而同样替换出 abc 呢? 

 

这个问题我们可用很轻松的用 eval 来解决:  

代码:

eval echo $A$a

 

说穿了, eval 只不过是在命令行完成替换重组后, 再来一次替换重组罢了... 

 

转载于:https://blog.51cto.com/qqtthappygo/955798

最后

以上就是纯真冬日最近收集整理的关于细读shell-6的全部内容,更多相关细读shell-6内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(294)

评论列表共有 0 条评论

立即
投稿
返回
顶部