文本處理三劍客簡介(grep、awk、sed)

本章內容:

命令 描述
awk 支持全部的正則表達式
sed 默認不支持擴展表達式,加-r 選項開啓 ERE,若是不加-r 使用花括號要加轉義符\{\}
grep 默認不支持擴展表達式,加-E 選項開啓 ERE,若是不加-E 使用花括號要加轉義符\{\}
egrep 支持基礎和擴展表達式

awk

推薦文章:http://www.javashuo.com/article/p-yeuxyalf-dk.htmlhtml

推薦文章:http://www.zsythink.net/?s=awklinux

awk不單單時linux系統中的一個命令,並且是一種編程語言,能夠用來處理數據和生成報告(excel)。處理的數據能夠是一個或多個文件,能夠是來自標準輸入,也能夠經過管道符獲取標準輸入,awk能夠在命令行上直接編輯命令進行操做,也能夠編寫成awk程序來進行更爲複雜的運用。三劍客老大!正則表達式

一、awk語法

awk [option] 'pattern {action}' filename

命令 + 選項 +   找誰 +   幹啥  +    文件名

option:
-F :指定分隔符(不指定默認以空格爲分隔符)編程

實例:數組

╭─root@localhost.localdomain ~  
╰─➤  awk ‘NR>=2&&NR<=5{print $0}’ test
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

分析awk處理過程:緩存

  1. 讀取文本第一行,首先會和匹配模式進行相匹配,若是發現第一行內容不和模式相匹配的話,就繼續讀取下一行
  2. 讀取到第二行發現和模式相匹配,就會執行花括號裏面的動做
  3. 而後繼續讀取下一行,發現和模式相匹配,就會執行花括號裏面的動做
  4. 依次讀取全文

二、awk基本概念及內置匹配變量

基本概念:bash

概念 屬性
記錄(record) 一行就是一個記錄
分隔符(field separator) 進行對記錄進行切割的時候所使用的字符
字段(field) 將一條記錄分割成的每一段
FILENAME 當前處理文件的文件名
FS(Field Separator) 字段分隔符(默認是以空格爲分隔符=)
NR(Number of Rrecord) 記錄的編號(awk每讀取一行,NR就加1==)
NF(Number of Field) 字段數量(記錄了當前這條記錄包含多少個字段==)
ORS(Output Record Separator) 指定輸出記錄分隔符
(指定在輸出結果中記錄末尾是什麼,默認是\n,也就是換行)
OFS(Output Field Separator) 輸出字段分隔符(默認值是一個空格)
RS 記錄分隔符(默認是一個換行符)

內置匹配變量:app

變量名 屬性
$1 $2 …$n 當前記錄的第n個字段,字段間由FS分隔
$NF 輸出最後一個字段
$0 輸出整條記錄

三、awk運算符

運算符 描述
= += -= *= /= %= ^= **= 賦值
|| 邏輯或
&& 邏輯與
~ ~! 匹配正則表達式和不匹配正則表達式
< <= > >= != == 關係運算符
+ - 加,減
* / & 乘,除與求餘
+ - ! 一元加,減和邏輯非
^ *** 求冪
++ -- 增長或減小,做爲前綴或後綴

四、awk-正則

基礎正則:dom

符號 描述
. 匹配任意單個字符(必須存在)
^ 匹配以某個字符開頭的行
$ 配以什麼字符結尾的行
* 匹配前面的一個字符出現0次或者屢次;eg:a*b
.* 表示任意長度的任意字符
[] 表示匹配括號內的一個字符
[^] 匹配[^字符]以外的任意一個字符
^[^] 匹配非[^字符]內字符開頭的行
\< 錨定 單詞首部;eg:\<root
\> 錨定 單詞尾部:eg:\>root

擴展正則:編程語言

符號 描述
+ 表示前面的字符至少出現1次的狀況
| 表示「或」
表示前面的字符至多出現1次的狀況

實例1:打印出來以root開頭的行

╭─root@localhost.localdomain ~  
╰─➤  awk '/^root/{print $0}' test
root:x:0:0:root:/root:/bin/bash
╭─root@localhost.localdomain ~  
╰─➤ awk '/^root/'test
root:x:0:0:root:/root:/bin/bash

實例2:第五個字段包含root的行

# 第五個字段包含root  打印出來( 「~ 」  正則匹配)

╭─root@localhost.localdomain ~  
╰─➤ awk -F ":"  '$5~/root/{print $0}'  test        
root:x:0:0:root:/root:/bin/bash

實例3:打印本機ip地址

╭─root@localhost.localdomain ~  
╰─➤  ip a|grep global|awk -F " +|/" '{print $3}'
192.168.137.6

# 或

╭─root@localhost.localdomain ~  
╰─➤  ip a|awk -F " +|/" '$0~/global/{print $3}'
192.168.137.6

五、awk完整模式-BEGIN模式與END模式

語法(awk基本結構):

awk BEGIN{coms}  /pattern/{coms}  END{coms}

awk + 開始模塊   +   找誰幹啥   +    結束模塊

awk數組

arrayname[string]=value
數組名[元素名]=值

實例1:

╭─root@localhost.localdomain ~  
╰─➤   cat test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
╭─root@localhost.localdomain ~  
╰─➤ awk 'BEGIN{i=0}/root/{i++}END{print i}' test
2
╭─root@localhost.localdomain ~  
╰─➤ awk '/root/{i++}END{print i}' test
2

實例2:統計訪問的網址

#用cut+sort+uniq的方法

╭─root@localhost.localdomain ~  
╰─➤   cat test | cut -d "/" -f 3 | sort | uniq -c | sort -rn
25 www.taobao.com
13 www.sina.com
7 www.qq.com

#用awk+sort的方法

╭─root@localhost.localdomain ~  
╰─➤  cat test | awk -F "/+" '{du[$2]++}END{ for ( i in du) print du[i],i}' | sort -rn
25 www.taobao.com
13 www.sina.com
7 www.qq.com

##分析awk都幹了些什麼?
#第一步:awk一行一行讀取test文件,切割出訪問域名eg:www.qq.com
#    定義一個數組:數組名爲du  元素名爲訪問域名
#    每行讀取到相同元素名,值+1        例:du[www.qq.com]+=1
#第二步:END模塊 for循環輸出數組;

sed

sed工做原理

  1. sed讀取一行,首先將這行放入到緩存中
  2. 而後,纔對這行進行處理
  3. 處理完成之後,將緩衝區的內容發送到終端
  • 存儲sed讀取到的內容的緩存區空間稱之爲:模式空間(Pattern Space)

sed選項

option:

選項 解釋說明
-n(no) 取消默認的sed的輸出,常與p連用
-e(entry) 多點操做
-r(ruguler) 使用使用擴展正則表達式,默認sed只識別基本正則表達式
-i(inside) 直接修改文件內容,而不是輸出到終端,
若是不使用-i選項sed軟件只是修改在內存中的數據,並不會影響磁盤上的文件

sed命令

command 解釋
a(append) 追加,在指定行後面添加一行或多行文本
i(insert) 插入,指在指定行前添加一行或多行文本
c(chenge) 取代指定行
d(delete) 刪除指定行
p(print ) 打印模式空間內容,一般與-n一塊兒使用
! 對指定行之外全部行應用命令

sed正刪改查

演示文件

╭─root@localhost.localdomain ~  
╰─➤  cat test       
this is the first line
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

1.增

實例1
a :追加,在指定行後面添加一行或多行文本

╭─root@localhost.localdomain ~  
╰─➤  sed "2a new" test     
this is the first line
this is the second line
new
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實例2
i : 指在指定行前添加一行或多行文本

╭─root@localhost.localdomain ~  
╰─➤  sed "2i new" test
this is the first line
new
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實例3
\n:同時添多行

╭─root@localhost.localdomain ~  
╰─➤  sed "2a new\nnew\nnew" test
this is the first line
this is the second line
new
new
new
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

二、刪

實例1
d:刪除全部

╭─root@localhost.localdomain ~  
╰─➤  sed "d" test

實例2
d:刪除指定行

╭─root@localhost.localdomain ~  
╰─➤  sed "3d" test
this is the first line
this is the second line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實例3
d:刪除範圍行

╭─root@localhost.localdomain ~  
╰─➤  sed "2,4d" test    
this is the first line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實例4
正則:刪除匹配行

╭─root@localhost.localdomain ~  
╰─➤  sed "/f.*/d" test
this is the second line
this is the third line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實例5
!:取反

╭─root@localhost.localdomain ~  
╰─➤  sed '/f.*/!d' test
this is the first line
this is the forth line
this is the fivth line

三、改

實例1
c(change):替換

╭─root@localhost.localdomain ~  
╰─➤  sed '2c change' test    
this is the first line
change
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實例2
s///g :替換

s:替換
g:全局替換
-i:直接修改文件內容(謹慎使用建議先備份)

╭─root@localhost.localdomain ~  
╰─➤  sed 's/is/ese/' test 
these is the first line
these is the second line
these is the third line
these is the forth line
these is the fivth line
these is the sixth line
these is the seventh line
these is the eighth line
these is the ninth line
these is the tenth line
╭─root@localhost.localdomain ~  
╰─➤  sed 's/is/ese/g' test
these ese the first line
these ese the second line
these ese the third line
these ese the forth line
these ese the fivth line
these ese the sixth line
these ese the seventh line
these ese the eighth line
these ese the ninth line
these ese the tenth line
# 尋找(以d開頭的行)並替換   

[root@localhost ~]# sed -i '/^d/ {s/ss/dd/g}' /root/test
[root@localhost ~]# a=dd
[root@localhost ~]# b=ss
[root@localhost ~]# sed -i '/^d/ {s/'$a'/'$b'/g}' /root/test
[root@localhost ~]# echo '$a'
$a

實例3
-r 擴展正則:指定替換

╭─root@localhost.localdomain ~  
╰─➤  sed -r 's/(first) line/\1 hang/g' test 
this is the first hang
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

四、查

實例1
p (print):輸出指定內容,但默認會輸出2次匹配的結果,所以使用-n選項取消默認輸出
/ / 正則:匹配

╭─root@localhost.localdomain ~  
╰─➤  sed -r -n '/f.*/p' test
this is the first line
this is the forth line
this is the fivth line

-e:多點操做

╭─root@localhost.localdomain ~  
╰─➤  sed -n -e '5p' -e '7p'  -e '1p' test    
this is the first line
this is the fivth line
this is the seventh line

grep

做用:過濾文本內容

選項 描述
-E :--extended--regexp 模式是擴展正則表達式(ERE)
-i :--ignore--case 忽略大小寫
-n: --line--number 打印行號
-o:--only--matching 只打印匹配的內容
-c:--count 只打印每一個文件匹配的行數
-B:--before--context=NUM 打印匹配的前幾行
-A:--after--context=NUM 打印匹配的後幾行
-C:--context=NUM 打印匹配的先後幾行
--color[=WHEN] 匹配的字體顏色,別名已定義了
-v:--invert--match 打印不匹配的行
-e 多點操做eg:grep -e "^s" -e "s$"

樣本文件內容

[root@ken ~]# cat test
dlakdlad
ad
ad
a
dFSAF
A
F
F
AS
F
f
sf
as
f

實例1:打印出全部的a不管大小寫 : -i選項

╭─root@localhost.localdomain ~  
╰─➤   grep -i 「a」 test
dlakdlad
ad
ad
a
dFSAF
A
AS
as

實例2:打印出全部的a不管大小寫,而且顯示該字符串所在的行 : -n選項

╭─root@localhost.localdomain ~  
╰─➤   grep -i -n 「a」 test
1:dlakdlad
2:ad
3:ad
4:a
5:dFSAF
6:A
9:AS
13:as

實例3:僅僅打印出全部匹配的字符串: -o選項

╭─root@localhost.localdomain ~  
╰─➤   grep -i -o 「a」 test
a
a
a
a
a
A
A
A
a

實例4:打印出匹配的字符串有多少行 -c選項

╭─root@localhost.localdomain ~  
╰─➤   grep -i -c 「a」 test
8

實例5:打印出字符S前面的2行 -B

╭─root@localhost.localdomain ~  
╰─➤  grep -B 2 「S」 test
ad
a
dFSAF
—
F
F
AS

實例6:打印出字符S後面的2行 -A

╭─root@localhost.localdomain ~  
╰─➤  grep -A 2 「S」 test
dFSAF
A
F
—
AS
F
f

實例7:打印出字符S先後2行 -C

╭─root@localhost.localdomain ~  
╰─➤   grep -C 2 「S」 test
ad
a
dFSAF
A
F
F
AS
F
f

實例8:打印出不包含大小s的全部行 取反 -v

╭─root@localhost.localdomain ~  
╰─➤   grep -i -v 「s」 test
dlakdlad
ad
ad
a
A
F
F
F
f
f

grep能夠從文件當中直接搜索某個關鍵詞,也能夠從標準輸入裏面搜錯

╭─root@localhost.localdomain ~  
╰─➤   grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
╭─root@localhost.localdomain ~  
╰─➤   cat /etc/passwd | grep 「root」
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

正則表達式(基於grep)

  • 功能就是用來檢索、替換那些符合某個模式(規則)的文本,正則表達式在每種語言中都會有;
  • 正則表達式就是爲了處理大量的文本或字符串而定義的一套規則和方法
  • 經過定義的這些特殊符號的輔助,系統管理員就能夠快速過濾,替換或輸出須要的字符串
  • Linux正則表達式通常以行爲單位處理

基礎正則表達式

符號 描述
. 匹配任意單個字符(必須存在)
^ 匹配以某個字符開頭的行
$ 配以什麼字符結尾的行
* 匹配前面的一個字符出現0次或者屢次;eg:a*b
.* 表示任意長度的任意字符
[] 表示匹配括號內的一個字符
[^] 匹配[^字符]以外的任意一個字符
^[^] 匹配非[^字符]內字符開頭的行
\< 錨定 單詞首部;eg:\<root
\> 錨定 單詞尾部:eg:\>root
\{m,n\} 表示匹配前面的字符出現至少m次,至多n次
\(\) 表示對某個單詞進行分組;\1表示第一個分組進行調用

擴展正則

  • egrep ...
  • grep -E ...
  • 擴展正則支持全部基礎正則;並有補充
  • 擴展正則中{}和[]不用轉義能夠直接使用;
符號 描述
+ 表示前面的字符至少出現1次的狀況
| 表示「或」
表示前面的字符至多出現1次的狀況

相關文章
相關標籤/搜索