- 一、正则表达式
- 1.1、正则表达式组成部分
- 1.2 匹配文本的所有单词
- 1.3、匹配IP地址
- 1.4、处理特殊字符用转义
- 二、grep
- 2.1、直接搜索匹配文本
- 2.2、从stdin 读取
- 2.3、对多个文本进行搜索
- 2.4 、-E
- 2.5、-o
- 2.6 -v
- 2.7 -c
- 2.8 统计匹配的数量
- 2.9、打印出包含匹配字符串的行号
- 2.10、打印模式匹配所位于的字符或字节偏移
- 2.11、搜索多个文件并找出匹配文本位于哪一个文件中
- 2.12 、递归搜索
- 2.13、忽略大小写
- 2.14 e和f
- 2.15、include和exclude
- 2.16、 结合xargs
- 2.17、-q
- 2.18 A、B、C
一、正则表达式
1.1、正则表达式组成部分
正则表达式 描 述 示 例
^ 行起始标记 ^tux 匹配以tux起始的行
$ 行尾标记 tux$ 匹配以tux结尾的行
. 匹配任意一个字符 Hack.匹配Hackl和Hacki,但是不能匹配Hackl2和Hackil,它只能匹配单个字符
[] 匹配包含在 [字符]之中的任意一个字符 coo[kl] 匹配cook或cool
[^] 匹配除 [^字符] 之外的任意一个字符 9[^01] 匹配92、93,但是不匹配91或90
[-] 匹配 [] 中指定范围内的任意一个字符 [1-5] 匹配从1~5的任意一个数字
? 匹配之前的项1次或0次 colou?r 匹配color或colour,但是不能匹配colouur
+匹配之前的项1次或多次 Rollno-9+ 匹配Rollno-99、Rollno-9,但是不能匹配Rollno-
匹配之前的项0次或多次 col 匹配cl、col、coool等
() 创建一个用于匹配的子串 ma(tri)?x 匹配max或maxtrix
{n} 匹配之前的项n次 [0-9]{3} 匹配任意一个三位数,[0-9]{3}可以扩展为[0-9][0-9][0-9]
{n,} 之前的项至少需要匹配n次 [0-9]{2,} 匹配任意一个两位或更多位的数字
{n,m} 指定之前的项所必需匹配的最小次数和最大次数 [0-9]{2,5} 匹配从两位数到五位数之间的任意一个数字
| 交替——匹配 | 两边的任意一项 Oct (1st | 2nd) 匹配Oct 1st或Oct 2nd
\ 转义符可以将上面介绍的特殊字符进行转义 a.b 匹配a.b,但不能匹配ajb。通过在 . 之间加上前缀 \ ,从而忽略了 . 的特殊意义
1.2 匹配文本的所有单词
(? [a-zA-Z]+ ?)
“ ? ”用于匹配单词前后可能出现的空格。 [a-zA-Z]+ 代表一个或多个字母(az和AZ)。
1.3、匹配IP地址
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
或者
[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}
[0-9] 或 [:digit:] 匹配数字0~9。 {1,3} 匹配1到3个数字, . 匹配 “.” 。
1.4、处理特殊字符用转义
$ 、 ^ 、 . 、 * 、 + 、 { 以及 } 等作为特殊字符。
当我们希望例如’ . ‘能够匹配字面意义上的’ . ',而非任意字符。所以我们在这个字符之前加上了一个反斜杠\
二、grep
grep 命令作为Unix中用于文本搜索的神奇工具,能够接受正则表达式,生成各种格式的输出。
grep全称是Global Regular Expression Print,表示全局正则表达式版本。
grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到标准输出,不影响原文件内容。
grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作
2.1、直接搜索匹配文本
grep root /etc/passwd
2.2、从stdin 读取
echo -e "this is a word\nnext line"
echo -e "this is a word\nnext line" | grep word
看到结果只显示了匹配的行。并把匹配的数据标红。
2.3、对多个文本进行搜索
语法 :grep “match_text” file1 file2 file3……
2.4 、-E
-E 选项——这意味着使用扩展(extended)正则表达式,或者也可以使用默认允许正则表达式的 grep 命令—— egrep
如下文本
this is a test regular expression
1 2 3 4 5
last line
只显示匹配字母
grep -E [a-z] grep/regular.txt
或者
grep -E "[a-z]" grep/regular.txt
2.5、-o
只输出符合 reg 的字符串
echo this is a text line. | egrep -o "[a-z]+\."
结果只会显示匹配的字符串line
2.6 -v
要打印除包含 match_pattern 行之外的所有行
选项 -v 可以将匹配结果进行反转(invert)。
grep -v "[a-z]" grep/regular.txt
只显示不匹配的字母的,即显示数字部分
2.7 -c
统计文件或文本中包含匹配字符串的行数:需要注意的是 -c 只是统计匹配行的数量,并不是匹配的次数
echo -e "1 2 3 4\nhello\n5 6" | egrep -c "[0-9]"
看到匹配了两行
2.8 统计匹配的数量
统计匹配的字符数需要结合wc命令
echo -e "1 2 3 4\nhello\n5 6" | egrep -o "[0-9]" | wc -l
看到匹配的次数即6个,
2.9、打印出包含匹配字符串的行号
grep -E -n "[a-z]" grep/regular.txt
2.10、打印模式匹配所位于的字符或字节偏移
echo "1 2 3 4hello5 6" | egrep -b -o "hello"
选项 -b 总是和 -o 配合使用
一行中字符串的字符偏移是从该行的第一个字符开始计算,起始值是0。在上面的
例子中," hello "的偏移值是7(也就是说, hello是从该行的第7个字符开始的,即“1 2 3 4hello5 6”这一行)
2.11、搜索多个文件并找出匹配文本位于哪一个文件中
grep -l linux sample1.txt sample2.txt
和 -l 相反的选项是 -L ,它会返回一个不匹配的文件列表
文本sample.txt和sample1.txt内容如下:
搜索包含Linux的文本:
grep -l linux sample.txt sample1.txt
可知两个文本都包含:
搜索包含java的文本:
grep -l java sample.txt sample1.txt
2.12 、递归搜索
如果需要在多级目录中对文本进行递归搜索,可以使用:
$ grep “text” . -R -n 搜索当前目录下 包含text的文本,并打印行号。
2.13、忽略大小写
echo hello world | grep -i "HELLO"
2.14 e和f
-e 指定多个匹配样式
匹配this和line:
echo this is a line of text | grep -e "this" -e "line" -o
grep -f 把样式放到文件中,
文件pat_file中放入hello和cool
搜索匹配文本中的字符串:
echo hello this is cool | grep -o -f pat_file
2.15、include和exclude
grep "this" study/ -r --include=*.{txt,sh}
–搜索所有包含this的txt和sh文件
注意这里 .{txt,sh} 扩展为.txt,*.sh
grep "this" study/ -r --exclude=*.{file,sh}
搜索匹配this但排除file和sh结尾的文件
2.16、 结合xargs
xargs 命令通常用于将文件名列表作为命令行参数提供给其他命令。当文件名用作命令行参数时,建议用0值字节作为文件名终止符,而非空格。因为一些文件名中会包含空格字符,一旦它被误解为终结符,那么单个文件名就会被认为是两个文件名(例如,New file.txt被解析成New和file.txt两个文件名)。这个问题可以利用0值字节后缀来避免。我们使用 xargs 以便从诸如 grep 、find 中接收 stdin 文本。这些命令可以将带有0值字节后缀的文本输出到 stdout 。为了指明输入的文件名是以0值字节( \0 )作为终止符,需要在 xargs 中使用 -0。
创建测试文件
echo "test" >file1
echo "cool" >file2
echo "test" >file3
grep "test" file* -lZ| xargs -0 rm
#找到含有test的file开头的文件并删除
2.17、-q
有时候,我们并不打算查看匹配的字符串,而只是想知道是否能够成功匹配。这可以通过设
置 grep 的静默选项( -q )来实现。在静默模式中, grep 命令不会输出任何内容。它仅是运行命
令,然后根据命令执行成功与否返回退出状态。
如果命令运行成功会返回0,如果失败则返回非0值
#!/bin/bash
# 文件名: silent_grep.sh
# 用途: 测试文件是否包含特定的文本内容
if [ $# -ne 2 ]; #如果参数不够 提示执行语法
then
echo "Usage: $0 match_text filename"
exit 1
fi
match_text=$1
filename=$2
grep -q "$match_text" $filename
if [ $? -eq 0 ]; then
echo "The text exists in the file"
else
echo "Text does not exist in the file"
fi
执行脚本
./slient_grep.sh "test" file1
./slient_grep.sh "test" file2
2.18 A、B、C
seq 10 | grep 5 -A 3 #a after
#要打印匹配5,并打印之后的3行
要打印匹配5,并打印之前的3行
seq 10 | grep 5 -B 3
3、要打印匹配某个结果之前以及之后的3行,使用 -C 选项
seq 10 | grep 5 -C 3
如果有多个匹配,那么使用 – 作为各部分之间的定界符:
echo -e "a\nb\nc\na\nc" | grep a -A 1