注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

编程学习

我的网上家园

 
 
 

日志

 
 

GREP 的用法,摘抄的.  

2013-05-30 17:11:23|  分类: 学习应用 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Unix GREP的用法

grep(全局正则表达式版本)允许对文本文件进行模式查找,grep支持基本正则表达式,也支持其扩展集。
grep有三种变形:
    grep 标准grep命令
    egrep 扩展grep命令,支持基本及扩展的正则表达式,但不支持\q模式范围的应用
    fgrep 快速grep命令,允许查找字符串而不是一个模式,不要误解fast,其实和grep速度相当

grep的一般格式:
    grep [选项] 基本正则表达式 [文件]   这里的基本正则表达式可为字符
使用双引号:
    字符串参数最好使用双引号扩起来,一是以防被误解为shell命令,二是可以用来查找多个单词组成的字符串,在调用变量的时候也要使用双引号,比如grep "$MYVAR",否则无结果,在调用模式匹配是,应使用单引号

grep的选项:
    -c 只输出匹配行的计数,比如grep -c "test" *.txt,将显示4,则说明包含test的有4行
    -i 不区分大小写(只适用于单字符),比如grep -i "Bank" *.c等同于grep -i "bank" *.c
    -h 查询多文件时不显示文件名
    -l 查询多文件时只输出包含匹配字符的文件名
    -n 显示匹配行及行号,在显示出内容的每行前面会显示行数
    -s 不显示不存在或无匹配文本的错误信息
    -v 显示不包含匹配文本的所有行,grep -v "test" abc.txt,将显示不包含"test"的行内容
    -w 以单词为单位进行匹配
    -E 允许使用扩展模式匹配

grep和正则表达式:
    使用正则表达式最好使用单引号括起来,避免参数被做为shell命令执行
    
^ 锚定行的开始 如:'^grep'匹配所有以grep开头的行。
    $ 锚定行的结束 如:'grep$'匹配所有以grep结尾的行。 
    . 匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。 
    * 匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。
    [] 匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。
    [^] 匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-F和H-Z字母开头,紧跟rep的行。 
    \(..\)标记匹配字符,如'\(love\)',love被标记为1。 
    \< 锚定单词的开始,如:'\<grep'匹配包含以grep开头的单词的行。 
    \> 锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。 
    x\{m\} 重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。 
    x\{m,\} 重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。 
    x\{m,n\} 重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。
    \w 匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。
    \W \w的反置形式,匹配一个或多个非单词字符,如点号句号等。
    \b 单词锁定符,如: '\bgrep\b'只匹配grep。

    模式范围: grep '48[a-z]' *.txt
    不匹配行首: grep '^[^48]' *.txt 查找行首不是48的行内容
    设置大小写: grep '[Ss]ept' *.txt 查找Sept和sept内容
    匹配任意字符: grep 'K...D' *.txt     grep '[A-Z][A-Z]..C' *.txt
     "与"和"或": grep -E '219|216' *.txt 查找包含219或者216的行内容
     空行: grep '^$' *.txt
     类名:[[:upper:]] -> [A-Z]         [[:lower:]]   ->    [a-z]
          [[:digit:]] ->   [0-9]       [[:alnum:]]   -> [0-9a-zA-Z]
          [[:space:]] -> 空格或者tab键 [[:alpha:]] ->   [a-zA-Z]
        grep '5[[:upper:]]' *.txt 等同于 grep '5[A-Z]' *.txt
     列出所有的目录   ls -l |grep '^d'      
    列出所有的非目录   ls -l |grep '^[^d]' 或 ls -l |grep -v '^d'


技巧:

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 '\<hello\>' | grep '\<world\>'

    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 '\<main\>' /usr/include/*.h

3.善用 -E

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

  1. #查看gcc帮助文件里两个the/that/and/or连在一起的行
  2. man gcc | grep -E '(\<the\>|\<that\>|\<and\>|\<or\>) \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

    


  评论这张
 
阅读(28)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017