免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 26560 | 回复: 42
打印 上一主题 下一主题

[文本处理] grep 技巧 11则 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-06 22:54 |只看该作者 |倒序浏览
本帖最后由 j3kljs02398j 于 2012-10-11 13:13 编辑

建议对文中命令进行亲自尝试与检验。

1. 多个关键字查找
        1.1 关键字间or操作(多个-e选项; 元字符\|; -f file)

  1.         # 多个-e选项
  2.         grep -l -e 'string\.h' -e 'stdlib\.h' /usr/include/*.h
  3.         # 使用\|
  4.         grep 'strint\.h\|stdlib\.h' /usr/include/*.h   
  5.         grep -E 'string\.h|stdlig\.h' /usr/include/*.h#使用-E 看着舒服
  6.         # 使用-f 指定文件
  7.         grep -l -f multi_pattern.txt /usr/include/*.h

复制代码

ps:  
        -e 选项可以避免 关键字是-开头的导致选项解读失败。但是书写不方便。
        启用-E后,可以用|来进行or操作, 这个是非常方便的。


        1.2 关键字间and操作(通过管道|; 通过正则)

  1.         # 通过管道
  2.         echo hello world | grep '\<hello\>' | grep '\<world\>'#同时包含'hello','world'的行
  3.         #通过正则对n个关键字全排序
  4.         grep -E 'pattern1.*pattern2|pattern2.*pattern1'#2个关键字还好,要是n!个关键字!      
复制代码

ps:
       当进行and匹配的时候, 还是喜欢用管道的方式。


2. 匹配单词(-w gnu选项; \<\>)

  1.         grep -w 'main' /usr/include/*.h#这个-w很方便
  2.         grep '\<main\>' /usr/include/*.h   
复制代码

ps:当不考虑可移植性的时候, -w代替/<...>/方便多了。


3.善用-E和-P(启用 extended expression和perl-regrexp,正则写起来更加灵活,省去很多的\,正则功能更强大)

  1.         man gcc | grep -E '(\<the\>|\<that\>|\<and\>|\<or\>) \1'#查看gcc帮助文件里两个the/that/and/or连在一起的行
  2.         man gcc | grep -E -w '(the|that|and|or) \1'
  3.         man gcc | grep -E -w '([a-zA-Z]+) \1'#查看gcc帮助文件里含两个连续单词的行
复制代码
ps:
       grep的强大依靠于正则使用。-P无所不能!



4. 忽略大小写 -i

  1.         grep -i 'int_max' /usr/include/limits.h #查看INT_MAX的值
  2.         echo 'it IT' | grep -i -w -E '([a-z]+) \1' #连个单词相同,因为忽略大小写
  3.         echo 'it IT' | grep -E  -w '([a-zA-Z]+) \1' #两个单词不同
复制代码
5. 递归查找 -r/R(posix 未说明)

  1.         grep -i -w -r -E 'error|failed|failure' /var/log |less #查看日志的错误信息
复制代码
ps:
        这个选项是我查找用的最多的, 鬼才知道哪个文件里包含我要的关键字。

6. 取反-v

  1.         grep -v -w 'hello' filename #如果没有取反,世界将不再美丽
复制代码
ps:
       作为程序员,没有人愿意失去取反操作

7. 匹配数 -c

  1.         echo aaaa | grep -c 'a' #这个输出是1!因为grep是行匹配的
复制代码
ps:
       可能脚本理常用吧


8. 输出文件名 -l

  1.         grep -l -r -i -w 'key_word' /usr/include/*.h #查找包含key_word的头文件
  2.         
复制代码
9. 只输出匹配部分-o (gnu 选项, 常用与检测正则表达式)

  1.         echo abcddf |grep -o 'dd'
  2.         
复制代码
ps:
        每次写正则,心里都没底, 所以我就不断用这个调试。


10. 如果是纯字符串搜索,-F 速度更快。(惟吾无为 12楼补充)
        做个实验:

  1.         man gcc | tr -cs '[:alpha:]' '\n' >grep.date #用gcc manual生成个纯字符串文件作为搜索关键字
  2.         wc -l grep.date
  3.         97288 #这么多!

  4.         time `man gcc | grep  -F -f grep.date > /dev/null` #比较不带-F,与带-F
  5.         real    0m0.499s #仔细看看时间的对比!
  6.         user    0m0.741s
  7.         sys     0m0.056s

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

11. 在查找进程的时候,利用[]实现同时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 #-v 去掉grep进程结果
  5.         tdlteman 22023 22006  0 Oct07 ?        00:09:58 java -jar slave.jar

  6.         [Bob]@[Fck_without_U]:[~]-> ps -ef | grep "[j]ava -jar"
  7.         tdlteman 22023 22006  0 Oct07 ?        00:09:58 java -jar slave.jar #看,神奇的事情发生了
复制代码
grep [j]ava-jar,使用了[j]就实现了-v的功能,原理很简单。
grep [j]ava-jar这个进程要在ps进程先启动,然后ps执行结束后, grep再继续运行。所以ps对其命令的记录是完全字符串的“grep [j]ava-jar”,
然后grep [j]ava-jar匹配, 但是进程解析后就是 grep java-jar。 神奇就发生了。下面的命令很清晰的呈现出来。

  1. ps -ef | tee pro.log | grep [b]ash
  2. cat pro.log | grep grep
  3. cu       6868  6795  0 13:07 pts/4    00:00:00 grep [b]ash
复制代码
ps:
       这个技巧本不知道, 楼下一位补充的。 然后就如获珍宝啊。严格来说, 这个才是真技巧!



诚请geeks添加, 本帖长期维护。

论坛徽章:
0
2 [报告]
发表于 2011-10-07 00:29 |只看该作者
顶个

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
3 [报告]
发表于 2011-10-07 08:40 |只看该作者
回复 1# j3kljs02398j


-P 让grep 更强大好用...

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2011-10-07 09:16 |只看该作者
着色

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
5 [报告]
发表于 2011-10-07 09:48 |只看该作者
1.4
  1. grep -E '(hello.*world|world.*hello)' urfile
复制代码

论坛徽章:
0
6 [报告]
发表于 2011-10-07 10:38 |只看该作者
回复 3# jason680


    聪明的大脑 + 完美的正则

论坛徽章:
0
7 [报告]
发表于 2011-10-07 10:40 |只看该作者
回复 5# Shell_HAT


    great!

要是匹配同时包含 "it" "is" "a" "joke"四个单词怎么办那?

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
8 [报告]
发表于 2011-10-07 11:26 |只看该作者
先要说明版本, 有些系统上,你给参数是不支持的。

论坛徽章:
1
巳蛇
日期:2013-10-28 15:55:33
9 [报告]
发表于 2011-10-07 11:32 |只看该作者
不错.

论坛徽章:
0
10 [报告]
发表于 2011-10-07 12:02 |只看该作者
回复 8# rdcwayx


    还是版主想的周到。
帖子更正了。提到的tips尽量是可移植的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP