grep三剑客入门与进阶指南

2022-09-28 20:15:21 浏览数 (1)

[TOC]

0x00 快速入门

描述: 不管对于那一门编程语言,字符串类型都是及其重要的,所以在学习编程语言后会发现近40%左右都与字符串有关,特别是PHP当然在Linux中的shell脚本开发也同样存在;所以下面主要是字符串搜索命令采用正则匹配的命令,都是在shell编程中比较常用的;

grep 命令

描述:grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

Tips:属于Linux三剑客之一(grep、sed、awk)

语法和参数:

代码语言:javascript复制
grep 【选项】"字符串"  文件名   #在文件中查找字符串

#参数选项
-a 不要忽略二进制数据。
-A <显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容。
-B <显示列数> 并显示该行之前的内容
-b 在显示符合范本样式的那一行之外,并显示该行之前的内容。
-c 计算符合范本样式的列数。
-C <显示列数>或-<显示列数>  除了显示符合范本样式的那一列之外,并显示该列之前后的内容。(中间开始上下列数)
-d <进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。
-e, --regexp=PATTERN #指定字符串作为查找文件内容的范本样式。 (常用即模式通配符匹配)
-E, --extended-regexp #支持正则匹配 grep需要使用正则表达式进行匹配 Expgress reg。(常用扩展正则匹配)
-G, --basic-regexp    #基础正则匹配
-P, --perl-regexp     #使用perl正则进行匹配
-f <范本文件> 指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。
-F 将范本样式视为固定字符串的列表。
-G 将范本样式视为普通的表示法来使用。
-h 在显示符合范本样式的那一列之前,不标示该列所属的文件名称。
-H 在显示符合范本样式的那一列之前,同时打印包括搜索字符串的文件。 (常用)
-i 忽略字符大小写的差别,因为Linux严格区分大小写(常用)
-l 列出文件内容符合指定的范本样式的文件名称。
-L 列出文件内容不符合指定的范本样式的文件名称。
-n 在显示符合范本样式的那一列之前,标示出该列的编号。
-q 不显示任何信息。
-R/-r 此参数的效果和指定“-d recurse”参数相同,递归搜索。(常用)
-s 不显示错误信息。
-v 反转查找,即搜索不包含字符串的文件 (显示除字符串的其他类容)。 (常用)
-w 只显示全字符合的列。
-x 只显示全列符合的列。
-y 此参数效果跟“-i”相同。
-Z 显示匹配的文件以及匹配字符
-o 只输出文件中匹配到的部分不会输出那一行,精确输出我想要的内容.(常用)

--color=auto # 标记匹配颜色选项
--include *  # 包含文件名称
--exclude *  # 排除文件名称
--exclude-from file  # 排除指定文件

实际案例:

代码语言:javascript复制
#示例1.grep常用参数选项
grep "match_pattern" file_name  #命令会返回一个包含“match_pattern”的文本行
grep -q "test" filename #静默输出不会输出任何信息,如果命令运行成功返回0,失败则返回非0值。一般用于条件测试。
grep -v "/" test.jsp  #反向查找显示(排查/字符的行)
grep -i "test" test.jsp  #忽略大小写
# TEST
grep -c "text" file_name  #统计文件或者文本中包含匹配字符串的行数 Tips:grep -c 要比 grep | wc -l
# 1
grep "text" -n file_name  #输出包含匹配字符串的行数
echo this is a text line | grep -e "is" -e "line" -o  #多个匹配样式
# is
# line
#也可以使用-f选项来匹配多个样式,在样式文件中逐行写出需要匹配的字符。
echo aaa bbb ccc ddd eee | grep -f patfile.txt -o


#示例2.在多个文件中查找
grep "match_pattern" file_1 file_2 file_3
grep "text" -n file_1 file_2
grep -l "text" file1 file2 file3 # 搜索多个文件并查找匹配文本在哪些文件中


#示例3.正则表达式匹配和精准输出-o
grep -E "[1-9] " #或egrep "[1-9] "
grep -v -E "^#" sshd.conf |
echo this is a test line. | grep -o -E "[a-z] ."
line.
echo this is a test line. | egrep -o "[a-z] ."
line.


#示例4.在多级目录中对文本进行递归搜索 -r
grep "text" . -r -n  # .表示当前目录。
echo -e "anbncnanbnc" | grep 'a' -A 0
a
--
a

WeiyiGeek.正则与递归

代码语言:javascript复制
#示例4.进阶使用
echo gun is not unix | grep -b -o "not"   #打印样式匹配所位于的字符或字节偏移:
# 7:not
#只在目录中所有的.php和.html文件中递归搜索字符"main()"
grep "main()" . -r --include *.{php,html}
#在搜索结果中排除所有README文件
grep "main()" . -r --exclude "README"
#在搜索结果中排除filelist文件列表里的文件
grep "main()" . -r --exclude-from filelist.txt

#使用0值字节后缀的grep与xargs:
#测试文件:
echo "aaa" > file1
echo "bbb" > file2
echo "aaa" > file3
grep "aaa" file* -lZ | xargs -0 rm
#执行后会删除file1和file3,grep输出用-Z选项来指定以0值字节作为终结符文件名(),xargs -0 读取输入并用0值字节终结符分隔文件名,然后删除匹配文件,-Z通常和-l结合使用。
$grep "aaa" file* -l
file1
file3
$grep "aaa" file* -Z
file1aaa
file3aaa
代码语言:javascript复制
# 示例5.打印出匹配文本之前或者之后的行
#显示匹配某个结果之后的3行,使用 -A 选项:
seq 10 | grep "5" -A 3

#显示匹配某个结果之前的3行,使用 -B 选项:
seq 10 | grep "5" -B 3

#显示匹配某个结果的前三行和后三行,使用 -C 选项:
seq 10 | grep "5" -C 3
#如果匹配结果有多个,会用“--”作为各匹配结果之间的分隔符:
echo -e "anbncnanbnc" | grep a -A 1
grep -E -A 3 "^Cached" meminfo  #显示后三行
# SwapCached:            0 kB
# Active:           163624 kB
# Inactive:         319796 kB

WeiyiGeek.grep-ABC

补充示例:

代码语言:javascript复制
# 示例6.grep采用perl正则元字符(环视功能)
echo "WeiyiWeiyiGeek Whoami" | grep -oP "Weiyi(?=WeiyiGeek)" #当后面接的字符串可以匹配出则显示,否则不显示
Weiyi
echo "WeiyiGeek Whoami" | grep -oP "(?=WeiyiGeek)Weiyi"
Weiyi

# 实例7.-o只输出匹配的perl正则元字符字符串
grep -Po '(?<=^ID=")w ' /etc/os-release
# centos

# 示例8.查询某一时间段后的100行
grep -A 100 "$(date -d '-1 minute' ' %Y-%m-%d %H:%M')" studentcenter.log

# 示例9.统计 18:05~18:10 时间段里面指定字符串的行数输出匹配的字符串(进行了过滤)
cd /app/logs/StudentCenter && egrep "18:(05|06|07|08|09|10)" info.2021-03-12.0.log | grep "cjxmc=总分" | egrep -o "sfzh=[1-9]d{5}(18|19|([23]d))d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]" | sort -u | wc -l
  # 合计: 2815 2736 2585 2639 2640 2574
# 统计那些人已经看了网页
cd /app/logs/StudentCenter && grep -E "21500140770323|21500113771228" info.2021-04-18.0.log | grep "yxmc=" | grep -oE "ksh=d{14}" | sort | uniq -c

# 示例10.匹配url的正则表达式(指定目录或者指定文件)
grep -ohr -E "https?://[a-zA-Z0-9./_&=@$%?~#-]*" ./folder
grep -oE '(https|http|ftp)?://[a-zA-Z0-9./_&=@$%?~#-]*' demo.txt | grep -vE ".docx$|.pdf$|.jpg$|.gif$" | sort | uniq

# 示例11.递归查询某一目录下不存在指定字符串的文件
grep -L "pageid:" -R  . | grep -E "md$"

注意事项:Find命令与Grep命令的区别 1)Find在系统中搜索的条件的文件名,如需要匹配,使用通配符匹配是完全匹配. 2)Grep在文件中搜索符号的字符串,如需匹配,则使用正则表达式是包含匹配

egrep 命令

描述:grep 默认仅支持基础正则表达式(Base Regular Expression),如果要使用扩展性正则表达式(Extended Regular Expression),使用egrep命令实际上grep -E == egrep ,extended regular expression比basic regular expression的表达更规范。

  • egrep用extended regular expression语法来解读的
  • grep用basic regular expression 语法解读

使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。

代码语言:javascript复制
egrep(选项)(查找模式)(文件名1,文件名2,……)
#选项
-i #ignore Capitailzation 忽略大小写

实际案例:

代码语言:javascript复制
#示例1.简单示例
$ egrep -n 'goo*d' regular_express.txt    #{0,N}
$ egrep -n 'go d' regular_express.txt    #{1,0}
$ egrep -n 'go?d' regular_express.txt    #{0,1}
$ egrep -n 'g(la|oo)d' regular_express.txt   #也就是搜寻(glad)或 good 这两个字符串
$echo'AxyzxyzxyzxyzC'|egrep 'A(xyz) C'
$echo'AxyzxyzxyzxyzC'|egrep 'A(xz) C'


#示例2.忽略大小写匹配
egrep -i '^(From|Subject|Date): ' email.txt

WeiyiGeek.正则egrep案例

0 人点赞