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)).

相關文章
相關標籤/搜索