本文已经迁移到最新内容请查看
<==使用技巧
1. 多个关键字查找
1.1 关键字间 or
i. 使用-e
-
#包含了string.h或者stdlib.h的头文件
-
grep -l -e 'string\.h' -e 'stdlib\.h' /usr/include/*.h
-e 选项还可以避免 关键字是-开头的导致选项解读失败。
ii. 使用元字符 \|
-
grep 'strint\.h\|stdlib\.h' /usr/include/*.h
-
#使用-E 看着舒服
-
grep -E 'string\.h|stdlig\.h' /usr/include/*.h
iii. 使用-f file
-
cat >multi_pattern
-
stdlib\.h
-
string\.h
-
grep -l -f multi_pattern /usr/include/*.h
1.2 关键字间 and
i. 通过管道
-
#同时包含'hello','world'的行
-
echo hello world | grep '\' | grep '\'
ii. 通过正则 |
-
grep -E 'pattern1.*pattern2|pattern2.*pattern1
如果包含2个关键字还好,要是n个就有n全排序列种可能!
2. 单词匹配
i. -w(gnu 选项)
-
grep -w 'main' /usr/include/*.h
这个-w很方便
ii. \<\>
-
grep '\' /usr/include/*.h
3.善用 -E
-E选项启用 extended expression,正则写起来更加灵活
-
#查看gcc帮助文件里两个the/that/and/or连在一起的行
-
man gcc | grep -E '(\|\|\|\) \1'
-
man gcc | grep -E -w '(the|that|and|or) \1'
-
#查看gcc帮助文件里含两个连续单词的行
-
man gcc | grep -E -w '([a-zA-Z] ) \1'
使用-E让书写更方便,省去很多的\,同时功能更强大。
4. 忽略大小写 -i
-
#查看INT_MAX的值
-
grep -i 'int_max' /usr/include/limits.h
-i与\n同时使用的乱象
-
#匹配连续相同单词
-
echo 'it IT' | grep -i -w -E '([a-z] ) \1'
-
echo 'it IT' | grep -E -w '([a-zA-Z] ) \1'
这是两个相同的单词吗?是的,因为告诉grep不计大小写的!
有的时候不要光图方便会不准确。
5. 递归查找 -r(posix 未说明)
-
#查看日志的错误信息
-
grep -i -w -r -E 'error|failed|failure' /var/log |less
6. 显示匹配行周围行 (posix 未说明)
B/A/C(before/after/context
-B n
-A n
-C n
7. 取反-v
-
grep -v -w 'hello' filename
如果没有取反,世界将不再美丽
8. 匹配数 -c
这个输出是1!因为grep是行匹配的
9. 输出文件名 -l
-
grep -l -r -i -w 'filename_max' /usr/include/*.h
10. 只输出匹配部分-o (gnu 选项)
-
echo abcddf |grep -o 'dd'
可以用于验证自己写的正则
11. 如果是纯字符串搜索,-F 速度更快。
做个实验:
-
#用gcc manual生成个纯字符串文件作为搜索关键字
-
man gcc | tr -cs '[:alpha:]' '\n' >grep.date
-
wc -l grep.date
-
97288 #这么多!
-
#比较不带-F,与带-F
-
time `man gcc | grep -F -f grep.date > /dev/null`
-
real 0m0.499s
-
user 0m0.741s
-
sys 0m0.056s
-
-
time `man gcc | grep -f grep.date > /dev/null`
-
real 4m9.630s
-
user 4m7.602s
-
sys 0m0.713s
仔细看看时间的对比!
当纯字符串匹配,尤其是要匹配的字符串非常多,-F不可不用。
12. 在查找进程的时候,利用[]实现同时grep -v grep的功能
举例:
-
[Bob]@[Fck_without_U]:[~]-> ps -ef | grep "java -jar"
-
tdlteman 22023 22006 0 Oct07 ? 00:09:58 java -jar slave.jar
-
xiabao 31501 30737 0 11:08 pts/8 00:00:00 grep java -jar ###grep 自身也出来了
-
-
[Bob]@[Fck_without_U]:[~]-> ps -ef | grep "java -jar" | grep -v grep
-
tdlteman 22023 22006 0 Oct07 ? 00:09:58 java -jar slave.jar
-
#grep -v grep 精确结果
-
[Bob]@[Fck_without_U]:[~]-> ps -ef | grep "[j]ava -jar"
-
tdlteman 22023 22006 0 Oct07 ? 00:09:58 java -jar slave.jar
-
#看,神奇的事情发生了
巧妙!
<==注意事项
1. [a-d] 与 [abcd] 不一定等价
正则表达式中出现range[]是里面的序列是受字符集和环境变量影响的。典型的,许多 locale 将字符以字典顺序排序,在这些 locale 中, [a-d] 不与 [abcd] 等价;例如它可能与 [aBbCcDd] 等价。
-
[iscs@linux-sp1]:/users/iscs>$ echo "ABC
-
> abc"|grep '[a-c]'
-
ABC
-
abc
-
[iscs@linux-sp1]:/users/iscs>$ echo "ABC
-
abc"|grep -E '[a-c]'
-
ABC
-
abc
为了提高可移植性:
1. 使用POSIX定义的字符组
2. 定义环境变量LC_ALL
2. 匹配 - 开头的关键字 如(--shit)grep出错
如果关键字以-开头,会打乱grep对选项的解析
解决:
使用 -e选项 或 --
-
[iscs@linux-sp1]:/users/iscs>$ echo "--shit"|grep --shit
-
grep: unrecognized option '--shit'
-
Usage: grep [OPTION]... PATTERN [FILE]...
-
Try `grep --help' for more information.
-
[iscs@linux-sp1]:/users/iscs>$ echo "--shit"|grep -- --shit
-
--shit
-
[test@test~]$ echo '--shit' | grep -e '--shit'
-
--shit
阅读(764) | 评论(0) | 转发(0) |