目录
1.grep简介
2.语法:
3.参数介绍:
3.1匹配模式
3.2匹配控制
3.3 输出控制操作(用于一般情况下)
3.4 输出行前缀控制(相当于awk的end模块,在输出每行之前在对行进行处理)
3.5 Context Line Control(也有点不明白)
3.6 文件和目录选择
3.7 其他选项
3.8 环境变量
4. 总结
简单介绍?grep是Linux下非常实用且次数使用非常多的文本过滤工具,并且也就是Linux三剑客之一(分别是awk,sed,grep)。grep主要为用户提供文件过滤,不提供对源文件进行修改,删除等操作,通过grep,你可以进一步精确自己的搜索范围。
运行原理?grep在默认情况会以指定的模式(4种模式)对输入文件(如果没有指定特定的文件,或者以 - 命令的文件,则使用标准输入来代替输入内容)进行查找,并且默认输出匹配的行。简单来说:grep使用基本正则表达式对文件进行搜索,并且默认输出匹配的行。除了grep之外还有egrep及fgrep为你提供。
egrep是grep扩展,简单来说就是支持扩展正则,而默认grep是以标准正则为基础,为用户提供匹配功能,默认是不支持扩展正则的。grep -E 等同于 egrep ,随便用哪个都行。
fgrep,是利用固定的字符串来对文本进行搜索,但不支持正则表达式的引用,所以此命令的执行速度也最快。fgrep 等同于 grep -F(本人没有怎么用过,具体用法也不知道)
官方不直接建议调用egrep或fgrep,但是支持此调用,具体为啥的话,我也不知道。
grep [选项] 模式 [文件...]
grep [选项] [-e 模式 | -f 文件] [文件...]
注:[] 这里面是可选的
3.1匹配模式
-E #开启egrep模式,支持扩展正则
-F #开启fgrep模式,现在也没有怎么弄清楚,后面遇到了在来更新
-G #默认设置,支持基本正则
-P #支持perl正则,也是一种正则表达式,但是我不会写,会写了在正则篇进行更新
注:我们日常使用最多的基本是默认设置(基本正则)及扩展正则。
3.2匹配控制
-e #支持多种模式匹配,简单来说是可以接多个匹配模块,如下例:
$ cat anaconda-ks.cfg | grep -e "^l" -e "^c" cdrom lang zh_CN.UTF-8 clearpart --none --initlabel chrony
-f #是从文本中获取匹配模式(条件),但是每行只能匹配一个,如果文件没有任何内容,则不匹配任何内容,如下例:
$ echo ^a >text.txt #不要输入 " "号 $ cat anaconda-ks.cfg | grep -f text.txt auth --enableshadow --passalgo=sha512 autopart --type=lvm
-i #忽略大小写,意思很直白
$ cat anaconda-ks.cfg | grep -i "^A" auth --enableshadow --passalgo=sha512 autopart --type=lvm
-v #取反,官方大致意思是:从匹配的文件中输出不匹配的行,是不是有点拗口,简单说:输出后面条件不匹配的行
$ cat anaconda-ks.cfg | grep -v "^$\|^#" auth --enableshadow --passalgo=sha512 cdrom graphical firstboot --enable ignoredisk --only-use=sda keyboard --vckeymap=cn --xlayouts='cn' #默认是输出以空格行及#号开头的行,加-v 就变成不输出符合这个条件的行
-w #匹配整个单词,如果字符串中含有这个单词,则不匹配,单词可由字母、数字和下划线组成(此行只要存在这个单词就可以被匹配出来)
$ cat anaconda-ks.cfg | grep "cdrom" cdrom #usecdromsdd ff $ cat anaconda-ks.cfg | grep -w "cdrom" cdrom #看到了吧,-w 后面的接单词,必须是完整,独立存在的
-x # -w的升级版,硬性条件,此行只能出现你所匹配的单词
$ cat anaconda-ks.cfg | grep "cdrom" cdrom cdrom asdc sdfr $ cat anaconda-ks.cfg | grep -x "cdrom" cdrom #根据上述结果,-x 后面的匹配条件 必须作为整行存在,不然就不会被匹配,-w 是所在行有那个单词即可
3.3 输出控制操作(用于一般情况下)
-B +number 显示当前匹配行的前number行
$ grep -B 2 qwe test.txt # -B 后面接数字就是显示当前匹配内容的前几行 456 789 qwe
-A +number 显示当前匹配行的后number行,-A跟-B刚好相反
$ grep -A 2 qwe test.txt #跟-B的功能是差不多的,但是显示数据的方向是不同的 qwe asd zxc
注:灵活使用-A -B 会使我们进行数据匹配更准确
-c #输出符合匹配条件的总行数,等于 wc -l 的统计功能,加 -v 反向选择
$ cat anaconda-ks.cfg | wc -l 49 $ cat anaconda-ks.cfg | grep -c "c" 24 $ cat anaconda-ks.cfg | grep "c" | wc -l 24 $ cat anaconda-ks.cfg | grep -c -v "c" 25 #根据上面数据显示,加上 -v 就是显示没有包含 c 的行数
--color[=WHEN] #对输出内容进行染色,颜色由环境变量GREP_COLORS定义(感兴趣的用户可以去了解一下)
-L -l ??(先跳过)
-m #后面接查询条件匹配行数(以匹配条件匹配的总行数为主,不是以文件的总航速为主),意思就是读到当前行是便终止查询,输出匹配到的行,可以组合 -c -v参数一起使用 -c就不演示了,打印行数的
$ cat anaconda-ks.cfg | grep -c an 7 $ cat anaconda-ks.cfg | grep -m 5 an # System language lang zh_CN.UTF-8 timezone Asia/Shanghai --isUtc %anaconda pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty #ok,你数数是不是5行,这个匹配规则是以你匹配内容的总行数为基数的。 $ cat anaconda-ks.cfg | grep -m 5 -v an #version=DEVEL # System authorization information auth --enableshadow --passalgo=sha512 # Use CDROM installation media cdrom # -m 5是默认打印符合 an 的条件的前5行,根据上面显示 加了 -v 打印还是前5行,但是是 属于符合 an 条件的前5行。在这里,-v还是反向选择的意思,但是有了限制条件,只能打印5行。
-o #只输出符合匹配的部分内容,每个部分单独的输出一行,应该做统计的时候会用到吧
$ cat anaconda-ks.cfg | grep -o "an" an an an an an an an #根据上述,只输出匹配内容
-q #不输出任何内容,官方介绍:如果有匹配项,则以零状态推出(不匹配),有错误信息也不输出,既简单来说,不输出任何内容
-s #不输出错误信息(是关于不存在或不可读的文件的错误消息)这种错误信息,本人也不知道怎么模拟,先跳过
3.4 输出行前缀控制(相当于awk的end模块,在输出每行之前在对行进行处理)
-b #官方说法:在输出的每一行之前,输出输入文件中基于0的字节偏移量。如果-o(—only-matching)是指定后,打印匹配部分本身的偏移量。(偏移量我好像了解的不够,这段先跳过)
-H #输出每个匹配的文件名,是搜索多个文件的默认设置,一般用于脚本,进行多文件匹配时,通过此参数获取文件名(后面有时间仔细研究一下)
$ cat anaconda-ks.cfg text.txt | grep -H an (标准输入):# System language (标准输入):lang zh_CN.UTF-8 (标准输入):timezone Asia/Shanghai --isUtc (标准输入):%anaconda (标准输入):pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty (标准输入):pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok (标准输入):pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty #好像与官方介绍的不一样
-h #跟-H相反,不输出文件名,用于单个文件搜索的默认设置
--label=LABE #输出文件标签,示例:gzip -cd foo.gz | grep --label=foo -H something 我也没有搞明白是咋回事
-n #输出的内容添加前缀 行号 (此行号是指你匹配的内容在整个文件中的位置)
$ cat anaconda-ks.cfg text.txt | grep -n an 14:# System language 15:lang zh_CN.UTF-8 26:timezone Asia/Shanghai --isUtc 45:%anaconda 46:pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty 47:pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok 48:pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty [root@localhost ~]# cat anaconda-ks.cfg | grep -n an 14:# System language 15:lang zh_CN.UTF-8 26:timezone Asia/Shanghai --isUtc #显示匹配内容行号,简单来说:输出匹配内容在源文件的位置
-T #与 -H -n -b 联合使用,主要是为输出带有前缀的参数提供制表符,使输出更加美观,如下例:
$ cat anaconda-ks.cfg | grep -m 3 -n an 14:# System language 15:lang zh_CN.UTF-8 26:timezone Asia/Shanghai --isUtc $ cat anaconda-ks.cfg | grep -m 3 -n -T an 14 :# System language 15 :lang zh_CN.UTF-8 26 :timezone Asia/Shanghai --isUtc #后面那个加了 -T 是不是展示更好看了些,貌似是对数字有用,其他的字符串好像没用
-Z #输出一个零字节,一般用于脚本类似于 $xbc=$x 这种,直接进行0值判断是判断不了的,可以与find-print0、perl-0、sort-z和xargs-0等命令一起使用,以处理任意文件名,甚至包含换行符的文件名。(不是怎么熟悉还不会测试)
3.5 Context Line Control(也有点不明白)
--group-separator=SEP #使用SEP作为分组符(默认sep分隔符是 - )
--no-group-separator #使用空格做分组符
#这2个参数好像是用于向后引用中的分隔符
3.6 文件和目录选择
-a 后面接文本类型的二进制文件 作用等同于 --binary-files=text #用处理普通文本的方法来处理二进制文件(具体用在啥地方我也不知道)
--binary-files=TYPE #官方的话如下:
如果文件的前几个字节表示该文件包含二进制数据,则假定该文件为type type。
默认情况下,TYPE是二进制的,grep通常输出一行消息,说明二进制文件匹配,如果没有匹配,则不输出消息。
如果类型不匹配,则grep假定二进制文件不匹配;这相当于-I选项。
如果类型是文本,grep处理二进制文件时就像处理文本一样;这相当于-a选项。
警告:grep——二进制文件=文本可能会输出二进制垃圾,如果输出是终端,并且终端驱动程序将其中一些解释为命令,则会产生糟糕的副作用。
-D #如果输入文件 是设备,FIFO或套接字,使用动作来处理它。默认情况是动作是可读的,支持正则搜索,如果动作被跳过的话,也就不会输出啥内容,简单来说: -D可以对设备,套接字类型文件以读的方式进行正则匹配。-d #如果输入是目录,则使用动作进行处理,也就是支持正则匹配。等价于-r
-exclude=glob #跳过以通配符匹配的内容,其中 glob 可以使用*、?和[…]作为通配符,需要转义了
--exclude-from=FILE #排除指定的文件
--exclude-dir=DIR #在递归搜索中排除指定目录
注:exclude 就是字面的意思
-I #大写的I,主要用于处理二进制文件,等同于 --binary-files=without-match (二进制数据本人没有处理过,也不了解先写这里,留个印象)
--include=GLOB # 只匹配符合 glob 规则的行(有空具体了解下glob是啥后再来补充)
-r # 递归读取每个目录下的文件,等价于 -d (前提是您搜索的内容是硬链接,软连接这种 ),只处理符号链接的内容-R #也是递归搜索每个目录下的文件,但是不同于-r,是处理所有文件(有点不太准确啊)
3.7 其他选项
--line-buffered #对输出的行启用缓冲功能,应该是适用于大规模过滤那种
-z -Z 完全没有搞明白
3.8 环境变量
GREP_COLORS #主要是对输出行进行染色,默认值是:ms=01;31:mc=01;31:sl=:cx=:fn=: 35:ln=32:bn=32:se=36(man手册有每个含义的介绍,直接使用默认的即可)
#环境变量写上的意义也不大,但是你得知道grep是受环境变量影响的,想对grep命令进行改装优化升级的那么得仔细阅读下环境变量,平常使用,默认即可。
EXIT STATUS #需要看下,以后再脚本或许能用到
通常,如果找到选定的行,则退出状态为0,否则为1。
但如果发生错误,则退出状态为2,除非使用了-q或——quiet或——silent选项并找到了所选的行。
但是,请注意,对于grep、cmp和diff等程序,POSIX只要求在发生错误时退出状态大于1;
因此,考虑到可移植性,最好使用测试这个通用条件的逻辑,而不是严格地与2相等。
注:grep的man手册到这里差不多就结束,至于为什么没讲正则了,因为man手册的正则也是一个概念,真正把常见的正则讲完,这里篇幅不够,并且文章长了,大家看的也累,所有拿出来单独讲,让自己及各位看官更清楚,至于环境变量,感兴趣的自己阅读mac手册,英语不行就翻译,就这样差不多了,其中还有些内容,我会在后面的时间补上的,如果没有补上,那就代表我还看不懂!
各位看官一定得看懂 grep工作原理,不然只掌握相关参数,不懂运行过程,在您写脚本,进行逻辑思考时候就会出现误差,走进死胡同,并且与同事进行交流时,也说不出个所以然,会很悲催的!看任何命令记得先了解运行过程!