Shell編程三劍客——grep、sed、awk詳解

在Linux/UNIX系統中包含不少文本處理器或文本編輯器,其中grep、sed和awk是shell編程中常常用到的文本處理工具,所以,被業內的人普遍的稱之爲「shell編程三劍客」html

grep命令工具

grep命令工具,在平常生活中,會常常用到,這裏也就很少說了,若是有不明白的朋友,請參考博文:Shell腳本應用之正則表達式詳解,裏面詳細介紹了grep命令的相關參數及使用,正則表達式

sed命令工具

sed是一個強大而簡單的文本解析轉換工具,能夠讀取文本,並根據指定的條件對文本內容進行編輯,最後輸出全部行活僅輸出處理的某些行,sed能夠在無交互的狀況下實現至關複雜的文本處理操做。被普遍的應用於shell腳本中,用於完成各類自動化處理任務。shell

sed的工做流程主要包括:
1. 讀取:sed從輸入流中讀取一行內容不可以存儲到臨時的緩衝區中;
2. 執行:默認狀況下全部的sed命令都在模式空間中按順序地執行,除非指定了行的地址,不然sed命令將會再全部行上依次執行;
3. 顯示:發送修改後的內容到輸出流,再發送數據後,模式空間將會被清空。
注意:在全部的文件內容都被處理完成以前,上述過程將重複執行,直至全部內容都被處理完。

1)sed命令的語法及相關參數:

sed [選項] '操做'  參數
或
sed [選項] -f scriptfile 參數

常見的sed命令選項的主要參數:
Shell編程三劍客——grep、sed、awk詳解
若是要求在第幾行到第幾行之間進行修改等,常見的操做參數包括:
Shell編程三劍客——grep、sed、awk詳解編程

2)sed命令用法示例(注意如下操做不會改變文件自己內容,若是須要修改必須帶「-i」選項)

1.輸出符合條件的文本
[root@localhost ~]# sed -n 'p' test.txt 
//輸出全部內容,等同於「cat test.txt」

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '3p' test.txt 
//輸出第三行內容

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '3,5p' test.txt 
//輸出3~5行

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n 'p;n' test.txt
//輸出全部奇數行,n表示讀入下一行數據

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n 'n;p' test.txt 
//輸出全部偶數行,n表示讀入下一行數據

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '1,5{p;n}' test.txt 
//輸出第1行~第5行之間的奇數行(第一、三、5行)

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '10,${n;p}' test.txt
//輸出第10行至文件尾部之間的偶數行(包括空行)

Shell編程三劍客——grep、sed、awk詳解

sed命令與正則表達式結合使用的案例
sed命令結合正則表達式時,格式略微有些不一樣,正則表達式以「/」包圍vim

[root@localhost ~]# sed -n '/the/p' test.txt
//輸出包含「the」的行

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '4,/the/p' test.txt
//輸出從第4行到都第一個包含「the」的行

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '/the/=' test.txt
//輸出包含「the」的行所在的行號(等號(=)用來輸出行號)

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '/^PI/p' test.txt
//輸出以「PI」開頭的行

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed -n '/\<wood\>/p' test.txt 
//輸出包含單詞wood的行,\<、\>表明單詞邊界

Shell編程三劍客——grep、sed、awk詳解

2.刪除符合條件的文本

nl命令用於計算文件的行數bash

[root@localhost ~]# nl test.txt | sed '3d'
//刪除第3行

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# nl test.txt | sed '3,5d'
//刪除第3~5行

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# nl test.txt | sed '/cross/d'
//刪除包含cross的行,本來的第8行被刪除

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# nl test.txt | sed '/cross/! d'
//刪除不包含cross的行

Shell編程三劍客——grep、sed、awk詳解

[root@localhost ~]# sed '/\.$/d' test.txt 
//刪除以「.」結束的行
[root@localhost ~]# sed '/^$/d' test.txt 
//刪除全部空行
[root@localhost ~]# sed -e '/^$/{n;/^$/d}' test.txt
//刪除空行,連續的空行留一個
3.替換符合條件的文本

使用sed命令進行替換操做時須要用到的選項:s(字符串替換)、c(整行/整塊替換)、y(字符轉換)等命令選項。因爲測試文件不符合要求,如下就不截圖了。編輯器

[root@localhost ~]# sed 's/the/THE/' test.txt
//將每行中的第一個the替換爲THE
[root@localhost ~]# sed 's/l/L/2' test.txt
//將每行中的第三個「l」替換爲「L」
[root@localhost ~]# sed 's/the/THE/g' test.txt 
//將文件中全部的「the」替換爲「THE」
[root@localhost ~]# sed 's/o//g' test.txt 
//將文件中全部的「o」刪除
[root@localhost ~]# sed 's/^/#/' test.txt 
//在每行的行首插入「#」號
[root@localhost ~]# sed '/the/s/^/#/' test.txt 
//在包含「the」的每行行首插入「#」號
[root@localhost ~]# sed 's/$/EOF/' test.txt 
//在每行行尾插入字符串「EOF」
[root@localhost ~]# sed '3,5s/the/THE/g' test.txt 
//將第3~5行中的全部「the」替換爲「THE」
[root@localhost ~]# sed '/the/s/o/O/g' test.txt 
//將包含「the」的全部行中的o替換爲「O」

以上「sed -i」的命令則是當即生效的!ide

[root@localhost ~]# sed -i '1c 1111' a.txt 
//替換文中第一行的內容爲「1111」
[root@localhost ~]# sed -i '1a 1111' a.txt 
//在第一行後面插入一行內容,內容爲「1111」
[root@localhost ~]# sed -i '1i 2222' a.txt
//在第一行前面插入一行內容,內容爲「2222」
[root@localhost ~]# sed -i '1d' a.txt
//刪除第一行內容
[root@localhost ~]# sed -n '1p' a.txt
//打印出第一行的內容
[root@localhost ~]# sed -i '1s/2222/3333/g' a.txt 
//將文本第一行內容「2222」替換爲「3333」
4.遷移符合條件的文本

使用sed命令進行遷移文本操做時須要用到的選項有:g、G將剪貼板中的數據覆蓋/追加到指定行;w保存爲文件;r讀取指定文件;a追加指定內容。工具

[root@localhost ~]# sed '/the/{H;d};$G' test.txt 
//將包含「the」的行遷移到文件末尾,「;」用於多個操做
[root@localhost ~]# sed '1,5{H;d};17G' test.txt 
//將第1~5行的內容轉移到第17行後
[root@localhost ~]# sed '/the/w out.file' test.txt 
//將包含「the」的行另存爲文件out.file
[root@localhost ~]# sed '/the/r /etc/hostname' test.txt 
//將文件/etc/hostname的內容添加到包含「the」的每行之後
[root@localhost ~]# sed '3aNEW' test.txt 
//在第3行後面插入一個新行,內容爲「NEW」
[root@localhost ~]# sed '/the/aNEW' test.txt 
//在包含「the」的每行後插入一個新行,內容爲「NEW」
[root@localhost ~]# sed '3aNEW1\nNEW2' test.txt
//在第3行後面多行內容,中間的「\n」表示換行
5.使用腳本編輯文件

使用sed腳本,將編輯指令存放到文件中(每行一條標記指令),經過「-f」選項來調用。學習

[root@localhost ~]# sed '1,5{H;d};17G' test.txt
//將第1~5行內容轉移至第17行後

Shell編程三劍客——grep、sed、awk詳解
以上操做轉換爲腳本文件方式:

[root@localhost ~]# vim 1.list
1,5H
1,5d
17G
[root@localhost ~]# sed -f 1.list test.txt

Shell編程三劍客——grep、sed、awk詳解

6.sed直接操做文件示例

編寫一個腳本,用來調整vsftpd服務配置:禁止匿名用戶,但容許本地用戶(也容許寫入)登陸。

[root@localhost ~]# vim local_only_ftp.sh
#!/bin/bash
S="/usr/share/doc/vsftpd-3.0.2/EXAMPLE/INSERNET_SITE/vsftpd.conf"
C="/etc/vsftpd/vsftpd.conf"
#指定樣本文件路徑、配置文件路徑
[ ! -e "$C.bak" ] && cp $C $C.bak
#備份原來的配置文件,檢測(配置文件.bak)是否存在,若是不存在則使用cp命令複製
sed -e '/^anonymous_enable/s/YES/NO/g' $S > $C
sed -i -e '/^local_enable/s/NO/YES/g' -e '/^write_enable/s/NO/YES/g' $C
grep "listen" $C || sed -i '$alisten=YES' $A
#基於樣本配置進行調整,覆蓋現有文件
systemctl restart vsftpd
systemctl enable vsftpd
#重啓ftp服務,並設置爲開機自啓動

awk命令工具

在Linux/UNIX系統中,awk是一個功能強大的編輯工具,逐行讀取輸入文本,並根據指定的匹配模式進行查找,對符合條件的內容進行格式化輸出或者過濾處理,能夠在無交互的狀況下實現至關複雜的文本操做,被普遍應用於Shell腳本,完成各類自動化配置任務。

1.awk命令的語法及概述
awk 選項  '模式或條件 { 編輯指令 }' 文件1 文件2 …  
//過濾並輸出文件符合條件的內容
awk  -f  腳本文件 文件1 文件2 …
//從腳本中調用編輯指令,過濾並輸出內容

*awk執行結果能夠經過print的功能將字段數據打印顯示。在使用awk命令的過程當中,可使用邏輯操做符「&&」和「||」;
也能夠進行簡單的數學運算,如+ 、-、
、/、%、^分別表示加、減、乘、除、取餘、乘方。**

awk從輸入文件或者標準輸入中讀入信息,與sed同樣,信息的讀入也是逐行讀取的。不一樣的是,awk命令將文本文件中的一行視爲一個記錄,而將一行中的某一部分(列)做爲記錄的一個字段。爲了操做這些不一樣的字段(列),awk借用shell中相似於位置變量的方法,用$一、$2…$9順序的表示不一樣列,$0表示整行。不一樣字段與不一樣字段能夠經過指定的方式進行分隔,awk默認的分隔符是空格。awk命令容許使用「-F分隔符」的形式來指定分隔符。

awk命令對/etc/passwd文件的處理過程如圖:
Shell編程三劍客——grep、sed、awk詳解

awk包含幾個特殊的內建變量,如:
Shell編程三劍客——grep、sed、awk詳解

2.awk命令用法示例
1)按行輸出文本
[root@localhost ~]# awk '{print}' test.txt 
//輸出全部內容,等同於「cat test.txt」
[root@localhost ~]# awk '{print $0}' test.txt
//輸出全部內容,等同於「cat test.txt」
[root@localhost ~]# awk 'NR==1,NR==3{print}' test.txt 
//輸出第1~3行的內容
[root@localhost ~]# awk '(NR>=1) && (NR<=3) {print}' test.txt 
//輸出第1~3行的內容
[root@localhost ~]# awk 'NR==1 || NR==3{print}' test.txt 
//輸出第1行、第3行的內容
[root@localhost ~]# awk '(NR%2)==1 {print}' test.txt 
//輸出全部奇數行的內容
[root@localhost ~]# awk '(NR%2)==0 {print}' test.txt 
//輸出全部偶數行的內容
[root@localhost ~]# awk '/^root/{print}' /etc/passwd
//輸出以「root」開頭的行
[root@localhost ~]# awk '/nologin$/{print}' /etc/passwd
//輸出以「nologin」結尾的行
[root@localhost ~]# awk 'BEGIN {x=0} ;/\/bin\/bash$/{x++};END {print x}' /etc/passwd
//統計以/bin/bash結尾的行數
[root@localhost ~]# grep -c "/bin/bash$" /etc/passwd
//統計以/bin/bash結尾的行數
[root@localhost ~]# awk 'BEGIN{RS=""}; END{print NR}' /etc/squid/squid.conf
//統計以空格分隔的文件段落數

注意:命令較多時,使用「BEGIN……END」

2)按字段輸出文本
[root@localhost ~]# awk '{print $3}' test.txt 
//輸出每行中(以空格分隔)的第3個字段
[root@localhost ~]# awk '{print $1,$3}' test.txt 
//輸出每行中(以空格分隔)的第1個和第3個字段
[root@localhost ~]# awk -F ":" '$2==""{print}' /etc/shadow
//輸出/etc/shadow文件中(以「:」分隔)的第二個字段(密碼爲空的用戶)
[root@localhost ~]# awk 'BEGIN {FS=":"}; $2=""{print}' /etc/shadow
//輸出/etc/shadow文件中(以「:」分隔)的第二個字段(密碼爲空的用戶)
[root@localhost ~]# awk -F ":" '$7~"/bash"{print $1}' /etc/passwd
//輸出以「:」分隔且第7個字段中包含「/bash」的行的第1個字段
[root@localhost ~]# awk '($1~"nfs") && (NF==8) {print $1,$2}' /etc/services
//輸出包含8個字段且第1個字段中包含「nfs」的行的第一、2個字段
[root@localhost ~]# awk -F ":" '($7!="/bin/bash") && ($7!="/sbin/nologin") {print}' /etc/passwd
//輸出第7個字段既不爲「/bin/bash」也不爲「/bin/nologin」的全部行
3)經過管道,雙引號調用Shell命令
[root@localhost ~]# awk -F: '/bash$/{print | "wc -l"}' /etc/passwd
//調用「wc -l」命令統計使用「bash」的用戶個數
[root@localhost ~]# grep -c "bash$" /etc/passwd
//同上一條命令同樣的做用
[root@localhost ~]# awk 'BEGIN {while ("w" | getline) n++ ; {print n-2}}'
//調用「w」命令,並用力啊統計在線用戶數
[root@localhost ~]# awk 'BEGIN { "hostname" | getline ; print $0}'
//調用「hostname」命令,並輸出當前用戶名
4)使用awk命令進行簡單的數學運算
[root@localhost ~]# awk 'BEGIN{ a=6;b=3;print"(a + b)=",(a + b)}'
(a + b)= 9
[root@localhost ~]# awk 'BEGIN{ a=6;b=3;print"(a - b)=",(a - b)}'
(a - b)= 3
[root@localhost ~]# awk 'BEGIN{ a=6;b=3;print"(a / b)=",(a / b)}'
(a / b)= 2
[root@localhost ~]# awk 'BEGIN{ a=6;b=3;print"(a % b)=",(a % b)}'
(a % b)= 0

更加詳細的awk命令,能夠參考博文:awk學習

相關文章
相關標籤/搜索