shell命令之grep
grep是强大的文本搜索工具,它以行为单位,在一个或多个文件中搜索字符串模板,模板后的所有字符串被看作文件名,搜索结果显示到标准输出,不影响原文件内容。搜索成功返回0,失败返回1,文件不存在时返回2。
正则表达式元字符
grep的强大之处在于模式串支持正则表达式,以下是常用的正则表达式元字符集:
- ^: 匹配行的开始
- $: 匹配行的结尾
- .: 匹配一个非换行字符
- []: 匹配指定范围内的一个字符
- [^]: 匹配一个不在指定范围内的字符
- (..): 标记匹配字符
- \<: 匹配单词的开始
- \>: 匹配单词的结尾
- x{m}: x字符重复m次
- x{m,}: x字符至少重复m次
- x{m,n}: x字符重复m~n次
- \w: 匹配一个字母、数字字符或下划线,即[a-zA-Z0-9_]
- \W: 匹配一个非字母非数字字符
- \d: 匹配一个数字字符,即[0-9]
- \D: 匹配一个非数字字符
- \s: 匹配一个空白字符
- \S: 匹配一个非空白字符
- ?: 匹配0次或1次前导字符
- +: 匹配1次或多次前导字符
- *: 匹配0次或多次前导字符
当然,grep也支持POSIX字符集。
常用选项
下面是grep常用的选项:
- -数字: 同时显示匹配行前后的若干行
- -B: 同时显示匹配行前的若干行
- -A: 同时显示匹配行后的若干行
- -c: 只显示匹配的行数,不显示匹配行的内容
- -E: 启用扩展正则表达式,相当于egrep
- -f file: 从文件中提取模板,空文件什么都不匹配
- -h: 搜索多个文件时,不显示文件名
- -i: 搜索时忽略大小写
- -I: 不搜索二进制文件
- -q: 静默模式,只返回退出状态
- -l: 打印匹配模板的文件列表
- -L: 打印不匹配模板的文件列表
- -n: 在匹配的行前面打印行号
- -o: 只打印模板匹配的部分内容
- -r: 递归搜索目录
- -s: 不显示关于不存在或无法读取文件的错误信息
- -v: 只显示不匹配的行
- -w: 搜索单词
注意事项
- 加号在[]外面时是一个特殊字符,如果在正则表达式中要匹配加号本身,需要用反斜杠转义。
- 当用加号指定一个或多个匹配字符集的字符时,加号要写在[]的外面,如果写在里面,也是一个合法的正则表达式,只不过含义变成一个包含有加号的字符集。
- 点号和加号被放到[]中时,不会再被认为是特殊字符,表示它本身,若用反斜杠转义它效果不变。
- 横杠-只有在字符集中时才是一个特殊字符,用来表示一个范围,如果在[]外边,它是一个普通字符,不需要转义。
实例
grep -rw --exclude "\*.c" "main" .
openssl md5 /etc/passwd | grep -Eo "[[:xdigit:]]{32}"
grep -Eo "\b[[:alpha:]]+\b" /etc/passwd | sort | uniq -c
grep -v "^$" file1 > file2
常用扩展
结合-o和-P选项,grep可以方便的提取需要的字符串,这里介绍两种常用的模式。
- (?<=pattern):匹配前缀,但不包含在匹配内容里。
- (?=pattern):匹配后缀,但不包含在匹配内容里。
比如,文本文件a.txt中内容如下:
"train_no":"5l0000G10241","station_train_code":"G102","start_station_telecode":"AOH"
提取车次可以用:grep -oP '(?<=station_train_code":")[^"]+(?=")' a.txt
。