3.4《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——grepping(检索目标行命令)

grep是检查文件内容最强大的工具之一,这也许不能表明什么,但这不是重点。的确,grep经常使用做动词,好比‘你彻底应该检索(grep)那个文件’.html

grep最经常使用于在文件中搜索子字符串。例如,咱们在第三章节中学到的在莎士比亚诗中搜索'rose'字符串。而使用grep,咱们能够直接找到标记,如Listing 16中展现的那样:正则表达式

Listing 16: 寻找出如今莎士比亚诗中的'rose'

$ grep rose sonnets.txt
The rose looks fair, but fairer we it deem
As the perfumed tincture of the roses.
Die to themselves. Sweet roses do not so;
Roses of shadow, since his rose is true?
Which, like a canker in the fragrant rose,
Nor praise the deep vermilion in the rose;
The roses fearfully on thorns did stand,
Save thou, my rose, in it thou art my all.
I have seen roses damask'd, red and white,
But no such roses see I in her cheeks;spring

使用Listing 16中的命令,看来咱们得用WC来计数‘rose’个数了(3.3章中介绍过), 正如Listing 17中:ubuntu

Listing 17:* 对grep的输出结果使用wc*

$ grep rose sonnets.txt | wc

10 82 419app

在上面👆Listing 17中咱们得知有10行包含'rose'(或'roses',由于'rose'是‘roses’的自字符串)。可是你可能在以前的插图12中看到莎士比亚的第一首诗就包含"Rose",以大写字母'R'开始,再看Listing 16,咱们会发现事实上这行被忽略了。这是由于grep默认要区分大小写字母,'rose'不匹配"Rose".less

正如你猜测那样,grep也有个选项能够改变大小区分匹配方式。要弄清楚是哪一个选项有个方法是搜索grepman手册页:工具

  • 输入 man grep
  • 在输入 /case 而后回车
  • 阅读结果(插图19)

(正如1.3章节中简洁批注样,手册页使用与3.3章遇到的less命令相同的用户界面,因此咱们能够经过/来搜索)学习


插图19: 在 man grep的结果中搜索'case'的结果

运用以上学到的知识像Listing 18那样操做。比较Listing 18和Listing 17的结果,咱们看到如今有12行匹配而不仅是10行了,因此诗中总共有12 -10 = 2行包含'Rose'(但不是'rose')。code

Listing 18: 不区分大小写的grep

$ grep -i rose sonnets.txt | wc
12 96 508server

grep工具很是很是强大,特别是与所谓的正则表达式结合在一块儿时,可是学习grepgrep -i几乎是很厉害的了(包括用grep搜索寻找过程当中的重要应用(Box 10)).在第四章中咱们会发现第三和最后个grep会变得更加厉害。

Box 10 搜索命令过程

grep的众多用途之一是过滤找到众多运行Unix进程的匹配进程。(在似Unix系统中,如Linux和macOS, 用户和每一个系统会各占进程,即定义好的容器中。)这对杀死流氓程序很是有用。(查找这些进程的好办法是运行‘stop’命令,它会显示消耗最多资源的进程。)

例如,在Ruby Rails的教程中里有一点,在进程列表中清除'spring'的程序很是重要。要清除的话,首先要找到这个进程,要查看系统中全部的进程用ps命令加上aux选项:
$ ps aux
图16, ps 是'process status'的简写。因为模糊不清,ps选项没有用短横线(因此它用ps aux 而不是 ps -aux)。(地球人怎么会懂?这正是本篇教程的目的,介绍这些知识。)

经过程序名过滤进程,你能够经过grep管道输出ps的结果:

$ ps aux | grep spring
ubuntu 12241 0.3 0.5 589960 178416 ? Ssl Sep20 1:46
spring app | sample_app | started 7 hours ago

结果中展现了一些进程的细节,可是最总要的是第一个数字,就是进程的id,或者pid(与kid发音押韵)。要清楚一个不想要的进程,咱们使用kill命令终止Unix代码pid(正好是15)的进程:

$ kill -15 12241

这是我建议杀死单个进程的技术,好比流氓网页服务(经过ps aux | grep server查找pid), 但有很容易杀掉与特定进程名匹配的全部进程,好比杀死全部消耗系统资源的'spring'进程。在这种状况下,能够像下面这样使用'pkill'杀死全部带有名'spring'的进程:

$ pkill -15 -f spring

不是全部时候都能如预期表现,或冻结一个进程,有个好办法是,运行top或者ps aux查看什么在运行,经过grep与ps aux选出可疑进程,而后在执行kill -15 或者 pkill -15 -f 这样就会更清楚了。

练习

  1. 经过搜索man grep手册页中的'line number', 构建命令查找sonnets.txt中'rose'出现的行数。
  2. 你应该发现了最后出现'rose'(匹配的 'roses')在2203行。弄清楚运行less sonnets.txt时作噩梦直接跳到这行。备注: 再查阅Table 4中,1G能够到文件的顶部,即就是1行。相似地,17G就到 17行等。

3.经过piping grep的输出head,只打印出'sonnets.txt'中包含'rose'的第一行。备注:使用3.2.2章节中的第二个练习。
4.在Listing 18中,咱们看到另外两个不区分大小写匹配'rose'。执行命名确认这两行都包含字符串"Rose"(而不是其余的,像'rOSe'). 备注: 使用匹配大小写的'grep'搜索"Rose".
5.在以前的练习中可能你已经发现了其实有3行匹配"Rose"而不是Listing 18中预期的2行。这是由于有一行即包含了"Rose"又包含了"rose", 所以在运行命令grep rosegrep -i rose时都出现了。写一条命令确认匹配“Rose”但不匹配"rose"的命令,预期是2。备注:pipe grep的结果和grep -v,而后将结果与wc管道输出。(-v是干吗的? 阅读grep的手册页(Box 5)).

相关文章
相关标签/搜索