grep用法

Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式,它的使用权限是所有用户。

grep 是一个很常见也很常用的命令,他最重要的功能就是进行字串数据的比对,然后将符合使用者需求的字串列印出来。需要说明的是『grep 在数据中查寻一个字串时,是以 "整行" 为单位来进行数据的撷取的!』也就是说,假如一个文件内有 10 行,其中有两行具有你所搜寻的字串,则将那两行显示在萤幕上,其他的就丢弃了!


tips:在关键字的显示方面,grep 可以使用 --color=auto 来将关键字部分使用颜色显示。这可是个很不错的功能啊!但是如果每次使用 grep 都得要自行加上 --color=auto 又显的很麻烦~此时那个好用的 alias 就得来处理一下啦!你可以在 ~/.bashrc 内加上这行:『aliasgrep='grep --color=auto'』再以『 source ~/.bashrc 』来立即生效即可喔!这样每次运行 grep 他都会自动帮你加上颜色显示啦!


查看grep帮助:man grep

语法:

grep  [options] pattern [filename]

选项:

-i   --ignore-case 

忽略大小写,pattern和file中的内容都忽略大小写


-n --line-number

输出显示行号


-v --invert-match

输出不匹配pattern的所有行


正则表达式:

[:alnum:]代表英文大小写字节及数字,亦即 0-9, A-Z, a-z
[:alpha:]代表任何英文大小写字节,亦即 A-Z, a-z
[:upper:]代表大写字节,亦即 A-Z
[:lower:]代表小写字节,亦即 a-z
[:digit:]代表数字而已,亦即 0-9

示例:

1. 利用中括号 [] 来搜寻集合字节

 如果想要搜寻do和to这两个单词时,可以这样来搜寻[td]o。其实 [] 里面不论有几个字节,他都谨代表某『一个』字节

 如果我不想要 o 前面有 t 的话呢?此时,可以利用在集合字节的反向选择 [^]来达成:


2. 行首与行尾字节 ^ $

如果我想要让 do 只在行首列出呢?这个时候就得要使用定位字节了!我们可以这样做:


如果我想要开头是小写字节的那一行就列出呢?可以这样:


同样的,上面的命令也可以用如下的方式来取代的:


好!那如果我不想要开头是英文字母,则可以是这样:


那个 ^ 符号,在字节集合符号(括号[])之内与之外是不同的!在 [] 内代表『反向选择』,在 [] 之外则代表定位在行首的意义要分清楚喔!反过来思考,那如果我想要找出来,行尾结束为小数点 (.) 的那一行,该如何处理:


特别注意到,因为小数点具有其他意义(底下会介绍),所以必须要使用跳脱字节(\)来加以解除其特殊意义!

那么如果我想要找出来,哪一行是『空白行』,也就是说,该行并没有输入任何数据,该如何搜寻?


因为只有行首跟行尾 (^$),所以,这样就可以找出空白行啦!再来,假设你已经知道在一个程序脚本(shell script) 或者是配置档当中,空白行与开头为 # 的那一行是注解,因此如果你要将数据列出给别人参考时,可以将这些数据省略掉以节省保贵的纸张,那么你可以怎么作呢?


输出非空白行和非注释行,可以通过‘|’进行连接。

3. 任意一个字节 . 与重复字节 *

我们知道万用字节 * 可以用来代表任意(0或多个)字节,但是正规表示法并不是万用字节,两者之间是不相同的!至於正规表示法当中的『 . 』则代表『绝对有一个任意字节』的意思!这两个符号在正规表示法的意义如下:

  • . (小数点):代表『一定有一个任意字节』的意思;
  • * (星星号):代表『重复前一个字节, 0 到无穷多次』的意思,为组合形态

这样讲不好懂,我们直接做个练习吧!假设我需要找出 g??d 的字串,亦即共有四个字节,起头是 g 而结束是 d ,我可以这样做:


因为 * 代表的是『重复 0 个或多个前面的 RE 字符』的意义,因此,『o*』代表的是:『拥有空字节或一个 o 以上的字节』,特别注意,因为允许空字节(就是有没有字节都可以的意思),因此,grep -n 'o*' regular_express.txt 』将会把所有的数据都列印出来萤幕上!

那如果是『oo*』呢?则第一个 o 肯定必须要存在,第二个 o 则是可有可无的多个 o ,所以,凡是含有 o, oo, ooo, oooo 等等,都可以被列出来~

同理,当我们需要『至少两个 o 以上的字串』时,就需要 ooo*

这样理解 * 的意义了吗?好了,现在出个练习,如果我想要字串开头与结尾都是 g,但是两个 g 之间仅能存在至少一个 o ,亦即是 gog, goog, gooog.... 等等,那该如何?


如此了解了吗?再来一题,如果我想要找出 g 开头与 g 结尾的字串,当中的字节可有可无,那该如何是好?是『g*g』吗?因为 g*g 里面的 g* 代表『空字节或一个以上的 g』在加上后面的 g ,因此,整个 RE 的内容就是 g, gg, ggg, gggg ,因此,只要该行当中拥有一个以上的 g 就符合所需了!

那该如何得到我们的 g....g 的需求呢?呵呵!就利用任意一个字节『.』啊!亦即是:『g.*g』的作法,因为 * 可以是 0 或多个重复前面的字符,而 . 是任意字节,所以:『.* 就代表零个或多个任意字节』的意思啦!


4. 限定连续 RE 字符范围 {}

在上个例题当中,我们可以利用 . 与 RE 字符及 * 来配置 0 个到无限多个重复字节,那如果我想要限制一个范围区间内的重复字节数呢?举例来说,我想要找出两个到五个 o 的连续字串,该如何作?这时候就得要使用到限定范围的字符 {} 了。但因为 { 与 } 的符号在 shell 是有特殊意义的,因此,我们必须要使用跳脱字符 \ 来让他失去特殊意义才行至於 {} 的语法是这样的,假设我要找到2个 o 的字串,可以是:


这样看似乎与 ooo* 的字符没有什么差异啊?因为第 8 行有多个 o 依旧也出现了!好,那么换个搜寻的字串,假设我们要找出 g 后面接 2 到 4 个 o ,然后再接一个 g 的字串,他会是这样:


第8行没出现因为有5个o,如果我想要的是 2 个 o 以上的 goooo....g 呢?


















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值