天天看點

shell三劍客 grep sed awk

shell 元字元

^ 行首定位符

$ 行尾定位符

. 任意單個字元

1. 比對前導符0到多次

.* 任意多個字元

[] 比對指定範圍内的一個字元

[-] 比對指定範圍内的一個字元

[^] 比對不在指定組内的字元

\ 用來轉義元字元 (” “” )

\< > 詞首和詞尾定位符

() 比對稍後使用的字元的标簽

x{m} 字元x重複出現m次

x{m,} 字元x重複出現m次以上

x{m,n}字元x重複出現m到n次

2. 比對一個或多個前導字元

? 比對零個或一個前導字元

a|b 比對a或b

grep

過濾,查找文檔中的内容 :grep 選項 比對模式  檔案

1. grep 支援基本正則

2. egrep 支援擴充正則

3. fgrep 不支援正則

傳回值:

  • 0 表示找到内容
  • 1 表示沒找到内容
  • 2 表示找的目錄不對

常用選項:

-q    靜默查詢結果

-v    取反查詢

-R    遞歸查詢目錄下的檔案

-A2   顯示查詢内容及後2行

-B2   顯示查詢内容及前2行

-C2   顯示查詢内容及前後各2行

egrep -l 隻顯示有查詢内容的檔案名

egrep -n  查詢結果帶行号

sed 流編輯

sed 是一種線上的、非互動式的編輯器,它一次處理一行内容。處理時,把目前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接着用sed指令處理緩沖區中的内容,處理完成後,把緩沖區的内容送往螢幕。接着處理下一行,這樣不斷重複,直到檔案末尾。檔案内容并沒有改變,除非你使用重定向存儲輸出。

文本檔案->“模式空間”(pattern space)->螢幕

逐行處理

内容未變

編輯檔案

格式:sed 選項 [模式]指令 檔案

常用選項:

-r  支援正則

-i  直接修改檔案内容

-n  靜默輸出

常用指令:

p  列印

d  删除

s  替換

c  整行替換

a  追加

i  插入

r  讀檔案

w  寫檔案

傳回值:隻有0,不管對錯

awk

用來切割和統計

文法:awk 選項 ‘BEGIN{} {} END{}’ 檔案名

原理:

(1)awk使用一行作為輸入,并将這一行賦給内部變量$0,每一行也可稱為一個記錄,以換行符結束

(2)然後,行被:(預設為空格或制表符)分解成字段(或域),每個字段存儲在已編号的變量中,從$1開始,

最多達100個字段

(3)awk輸出之後,将從檔案中擷取另一行,并将其存儲在$0中,覆寫原來的内容,然後将新的字元串分隔

成字段并進行處理。該過程将持續到所有行處理完畢

模式和動作:

任何awk語句都由模式和動作組成。模式部分決定動作語句何時觸發及觸發事件。處理即對資料進行的操作。如果省略模式部分,動作将時刻保持執行狀态。

模式可以是任何條件語句或複合語句或正規表達式。

模式包括兩個特殊字段 BEGIN和END。

BEGIN語句使用在任何文本浏覽動作之前

END語句用來在awk完成文本浏覽動作後列印輸出文本總數和結尾狀态。

條件表達式: awk -F: ‘{ if() {} }’ /etc/passwd

[root@localhost ~]# awk -F: '{ if($3<5) {print $0} }' /etc/passwd
root:x:::root:/root:/bin/bash
bin:x:::bin:/bin:/sbin/nologin
daemon:x:::daemon:/sbin:/sbin/nologin
adm:x:::adm:/var/adm:/sbin/nologin
lp:x:::lp:/var/spool/lpd:/sbin/nologin
           

循環:

awk ‘BEGIN{for(i=1;i<=5;i++){print i} }’

awk ‘BEGIN{ i=1; while(i<=10){print i; i++} }’

數組:

awk -F: ‘{username[x++]=$1} END{for(i in username) {print i,username[i]} }’ /etc/passwd

常用案例:

  1. 統計/etc/passwd中各種類型shell的數量
    awk -F: ‘{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }’ /etc/passwd
  2. 網站通路狀态統計 <目前時實狀态 netstat>
    netstat -ant |grep :80 |awk ‘{access_stat[$NF]++} END{for(i in access_stat ){print i,access_stat[i]}}’
  3. 統計目前通路的每個IP的連接配接數量 <目前時實狀态 netstat,ss>
    ss -an |grep :80 |awk -F”:” ‘!/LISTEN/{ip_count[$(NF-1)]++} END{for(i in ip_count){print i,ip_count[i]}}’ |sort -k2 -rn |head
  4. 統計Apache/Nginx日志中某一天的PV量  <統計日志>
    grep '07/Aug/2012' access_log |awk '{ips[$1]++} END{for(i in ips){print i,ips[i]} }' |awk '$2>100' |sort -k2 -rn