Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30677
  • 博文数量: 3
  • 博客积分: 197
  • 博客等级: 入伍新兵
  • 技术积分: 40
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-18 00:48
文章分类
文章存档

2012年(1)

2011年(1)

2010年(1)

分类:

2011-10-09 01:31:17

原文地址:grep 技巧10则 作者:j3kljs02398j


本文已经迁移到最新内容请查看


<==使用技巧

1. 多个关键字查找

  
  1.1 关键字间 or

    i. 使用-e

  1. #包含了string.h或者stdlib.h的头文件
  2. grep -l -e 'string\.h' -e 'stdlib\.h' /usr/include/*.h
    -e 选项还可以避免 关键字是-开头的导致选项解读失败。

   
ii. 使用元字符 \|

  1. grep 'strint\.h\|stdlib\.h' /usr/include/*.h
  2. #使用-E 看着舒服
  3. grep -E 'string\.h|stdlig\.h' /usr/include/*.h
    iii. 使用-f file
  1. cat >multi_pattern
  2. stdlib\.h
  3. string\.h
  4. grep -l -f multi_pattern /usr/include/*.h
    1.2 关键字间 and

    i. 通过管道


  1. #同时包含'hello','world'的行
  2. echo hello world | grep '\' | grep '\'
    ii. 通过正则 |

  1. grep -E 'pattern1.*pattern2|pattern2.*pattern1
    如果包含2个关键字还好,要是n个就有n全排序列种可能!   

2. 单词匹配

    i. -w(gnu 选项)

  1. grep -w 'main' /usr/include/*.h
    这个-w很方便

  
  ii. \<\>
  1. grep '\' /usr/include/*.h
3.善用 -E

    -E选项启用 extended expression,正则写起来更加灵活

  1. #查看gcc帮助文件里两个the/that/and/or连在一起的行
  2. man gcc | grep -E '(\|\|\|\) \1'
  3. man gcc | grep -E -w '(the|that|and|or) \1'
  4. #查看gcc帮助文件里含两个连续单词的行
  5. man gcc | grep -E -w '([a-zA-Z] ) \1'
    使用-E让书写更方便,省去很多的\,同时功能更强大。

4. 忽略大小写 -i

  1. #查看INT_MAX的值
  2. grep -i 'int_max' /usr/include/limits.h
    -i与\n同时使用的乱象

  1. #匹配连续相同单词
  2. echo 'it IT' | grep -i -w -E '([a-z] ) \1'
  3. echo 'it IT' | grep -E -w '([a-zA-Z] ) \1'
    这是两个相同的单词吗?是的,因为告诉grep不计大小写的!   
    有的时候不要光图方便会不准确。


5. 递归查找 -r(posix 未说明)

  1. #查看日志的错误信息
  2. 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

  1. grep -v -w 'hello' filename
    如果没有取反,世界将不再美丽

8. 匹配数 -c

  1. echo aaaa | grep -c 'a'
    这个输出是1!因为grep是行匹配的

9. 输出文件名 -l

  1. grep -l -r -i -w 'filename_max' /usr/include/*.h

10. 只输出匹配部分-o (gnu 选项)

  1. echo abcddf |grep -o 'dd'
    可以用于验证自己写的正则

11. 如果是纯字符串搜索,-F 速度更快。

    做个实验:
   
  1. #用gcc manual生成个纯字符串文件作为搜索关键字
  2. man gcc | tr -cs '[:alpha:]' '\n' >grep.date
  3. wc -l grep.date
  4. 97288 #这么多!      
   
  1. #比较不带-F,与带-F
  2. time `man gcc | grep -F -f grep.date > /dev/null`
  3. real 0m0.499s
  4. user 0m0.741s
  5. sys 0m0.056s

  6. time `man gcc | grep -f grep.date > /dev/null`
  7. real 4m9.630s
  8. user 4m7.602s
  9. sys 0m0.713s
   
  
  仔细看看时间的对比!
    当纯字符串匹配,尤其是要匹配的字符串非常多,-F不可不用。


12. 在查找进程的时候,利用[]实现同时grep -v grep的功能

    举例:
   
  1. [Bob]@[Fck_without_U]:[~]-> ps -ef | grep "java -jar"
  2. tdlteman 22023 22006 0 Oct07 ? 00:09:58 java -jar slave.jar
  3. xiabao 31501 30737 0 11:08 pts/8 00:00:00 grep java -jar ###grep 自身也出来了

  4. [Bob]@[Fck_without_U]:[~]-> ps -ef | grep "java -jar" | grep -v grep
  5. tdlteman 22023 22006 0 Oct07 ? 00:09:58 java -jar slave.jar
  6. #grep -v grep 精确结果
  7. [Bob]@[Fck_without_U]:[~]-> ps -ef | grep "[j]ava -jar"
  8. tdlteman 22023 22006 0 Oct07 ? 00:09:58 java -jar slave.jar
  9. #看,神奇的事情发生了
    巧妙!

<==注意事项

1. [a-d] 与 [abcd] 不一定等价

    正则表达式中出现range[]是里面的序列是受字符集和环境变量影响的。典型的,许多 locale 将字符以字典顺序排序,在这些 locale 中, [a-d] 不与 [abcd] 等价;例如它可能与 [aBbCcDd] 等价。
  
 
  

  1. [iscs@linux-sp1]:/users/iscs>$ echo "ABC
  2. > abc"|grep '[a-c]'
  3. ABC
  4. abc
  5. [iscs@linux-sp1]:/users/iscs>$ echo "ABC
  6. abc"|grep -E '[a-c]'
  7. ABC
  8. abc
    为了提高可移植性:
  
  1. 使用POSIX定义的字符组
    2. 定义环境变量LC_ALL


2. 匹配 - 开头的关键字 如(--shit)grep出错

    如果关键字以-开头,会打乱grep对选项的解析
    解决:
  
  使用 -e选项 或 --
   
  
 
  1. [iscs@linux-sp1]:/users/iscs>$ echo "--shit"|grep --shit
  2. grep: unrecognized option '--shit'
  3. Usage: grep [OPTION]... PATTERN [FILE]...
  4. Try `grep --help' for more information.
  5. [iscs@linux-sp1]:/users/iscs>$ echo "--shit"|grep -- --shit
  6. --shit
  7. [test@test~]$ echo '--shit' | grep -e '--shit'
  8. --shit
   


阅读(1233) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~