grep详解(参照man手册的,但是本篇不谈正则表达式)

目录

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. 总结


1.grep简介

简单介绍?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,但是支持此调用,具体为啥的话,我也不知道。

2.语法:

       grep [选项] 模式 [文件...]
       grep [选项] [-e 模式 | -f 文件] [文件...]

       注:[] 这里面是可选的

3.参数介绍:

 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相等。

4. 总结

注:grep的man手册到这里差不多就结束,至于为什么没讲正则了,因为man手册的正则也是一个概念,真正把常见的正则讲完,这里篇幅不够,并且文章长了,大家看的也累,所有拿出来单独讲,让自己及各位看官更清楚,至于环境变量,感兴趣的自己阅读mac手册,英语不行就翻译,就这样差不多了,其中还有些内容,我会在后面的时间补上的,如果没有补上,那就代表我还看不懂!

各位看官一定得看懂 grep工作原理,不然只掌握相关参数,不懂运行过程,在您写脚本,进行逻辑思考时候就会出现误差,走进死胡同,并且与同事进行交流时,也说不出个所以然,会很悲催的!看任何命令记得先了解运行过程!

你可能感兴趣的:(shell编程,grep详解,grep)