文本處理三劍客之sed編輯器和awk

一、sed編輯器

grep、sed、awk是文本處理三劍客

sed是一種流編輯器,流編輯器會在編輯器處理數據之前基於預先提供的一組規則來編輯數據流。
sed編輯器可以根據命令來處理數據流中的數據,這些命令要麼從命令行中輸入,要麼存儲在一個命令文本文件中。

sed 的工作流程及命令格式

sed 的工作流程主要包括讀取、執行和顯示三個過程:
●讀取:sed從輸入流(文件、管道、標準輸入)中讀取一行內容並存儲到臨時的緩衝區中(又稱模式空間,pattern space)
●執行:默認情況下,所有的sed命令都在模式空間中順序地執行,除非指定了行的地址,否則sed命令將會在所有的行上依次執行。
●顯示:發送修改後的內容到輸出流。在發送數據後,模式空間將會被清空。在所有的文件內容都被處理完成之前,.上述過程將重複執行,直至所有內容被處理完。

在所有的文件內容都被處理完成之前,上述過程將重複執行,直至所有內容被處理完。
注意:默認情況下所有的sed命令都是在模式空間內執行的,因此輸入的文件並不會發生任何變化,除非是用重定向存儲輸出。

命令格式:
sed -e ‘操作’ 文件1 文件2
sed -n -e ‘操作’ 文件1 文件2
sed -f 腳本文件 文件1 文件2 …
sed -i -e ‘操作’ 文件1 文件2 …



sed -e 'n{
操作1
操作2
}'文件1文件2 …


常用選項:
-e或–expression=:表示用指定命令來處理輸入的文本文件,只有一個操作命令時可省略,一般在執行多個操作命令使用
-f或- -file=:表示用指定的腳本文件來處理輸入的文本文件。
-h或–help:顯示幫助。
-n、- -quiet或silent:禁止sed編輯器輸出,但可以與p命令一起使用完成輸出。
-i:直接修改目標文本文件。




常用操作:
s:替換,替換指定字符。
d: 刪除,刪除選定的行。
a:增加,在當前行下面增加一行指定內容。
i:插入,在選定行上面插入一zai行指定內容。
c:替換,將選定行替換爲指定內容。
y:字符轉換,轉換前後的字符長度必須相同。
p:打印,如果同時指定行,表示打印指定行;如果不指定行,則表示打印所有內容;如果有非打印字符,則以ASCII碼輸出。其通常與“-n”選項一起使用。
=:打印行號。
l (小寫L):打印數據流中的文本和不可打印的ASCII字符(比如結束符$、製表符\t)








打印內容:

打印內容:
sed -n -e 'p' testfile1
sed -n -e '=' testfile1
sed -n -e 'l' testfile1
sed -n -e '!=;p' testfile1
sed -n -e '=' -e 'p' testfile1

sed -n '
>=
>p
> ' testfile1

sed -n -e ‘p’ testfile1       #打印出testfile1的內容,一般只有一個操作命令時可省略-e
在這裏插入圖片描述

sed -n -e ‘=’ testfile1     #打印出testfile1的內容的行號
在這裏插入圖片描述

sed -n -e ‘l’ testfile1     #打印數據流中的文本和不可打印的ASCII字符(比如結束符$、製表符\t)
在這裏插入圖片描述

sed -n -e ‘=’ -e ‘p’ testfile1      #輸出testfile1的行號和內容
sed -n -e ‘!=;p’ testfile1       #不輸出行號,至輸出內容
在這裏插入圖片描述
在這裏插入圖片描述


使用地址:

sed編輯器有2種尋址方式:
1、以數字形式表示行區間
2、用文本模式來過濾出行

sed -n '1p' testfile1			   	 #打印第一行
sed -n '$p' testfile1				 #打印最後一行
sed -n '1,3p' testfile1				 #打印1-3行
sed -n '3, $p' testfile1			 #打印3至最後一行
sed -n '1, +3p' testfile1        	 #打印1之後的連續3行,即1-4行
sed '5q' testfile1 		       		 #打印前5行信息後退出,q表示退出
sed -n 'p;n' testfile1				 #打印奇數行; n表示移動到下一行
sed -n 'n;p' testfile1				 #打印偶數行
sed -n '2,${n;p}' testfile1			 #打印從3開始的奇數行

sed -n '/user/p' /etc/passwd		 #打印/etc/passwd中含有user的行
sed -n '/^a/p' /etc/passwd			 #打印/etc/passwd中以a開頭的行
sed -n '/bash$/p' /etc/passwd		 #打印出/etc/passwd中以/bash結尾的行
sed -n '/ftp\|root/p' /etc/passwd	 #打印出帶有root或ftp的行
sed -n '2,/nobody/p' /etc/passwd	 #打印出第二行到第一個帶有nobady的行
sed -n '2,/nobody/=' /etc/passwd	 #打印出第二行到第一個帶有nobady的行的行號
sed -nr '/ro{1,}t/p' /etc/passwd	 #-r表示支持正則表達式 #打印出以r開頭至少有一個o的單詞的所在行

sed -n ‘1p’ testfile1    #打印第一行
在這裏插入圖片描述
sed -n ‘$p’ testfile1    #打印最後一行
在這裏插入圖片描述
sed -n ‘1,3p’ testfile1   #打印1-3行
在這裏插入圖片描述
sed -n ‘3, $p’ testfile1    #打印3至最後一行
在這裏插入圖片描述
sed -n ‘1, +3p’ testfile1   #打印1之後的連續3行,即1-4行
在這裏插入圖片描述
sed ‘5q’ testfile1      #打印前5行信息後退出,q表示退出
在這裏插入圖片描述
sed -n ‘p;n’ testfile1    #打印奇數行; n表示移動到下一行
在這裏插入圖片描述
sed -n ‘n;p’ testfile1     #打印偶數行
在這裏插入圖片描述














sed -n ‘2,${n;p}’ testfile1     #打印從3開始的奇數行
在這裏插入圖片描述
sed -n ‘/user/p’ /etc/passwd     #打印/etc/passwd中含有user的行
在這裏插入圖片描述
sed -n ‘/^a/p’ /etc/passwd     #打印出/etc/passwd中以a開頭的行
在這裏插入圖片描述




sed -n ‘/bash$/p’ /etc/passwd #打印出/etc/passwd中以/bash結尾的行
在這裏插入圖片描述
sed -n ‘/ftp|root/p’ /etc/passwd   #打印出etc/passwd中帶有ftp或root的行
在這裏插入圖片描述
sed -n ‘2,/nobody/p’ /etc/passwd   #打印出第二行到第一個帶有nobady的行
sed -n ‘2,/nobody/=’ /etc/passwd   #打印出第二行到第一個待遇哦nobady的行的行號
在這裏插入圖片描述
sed -nr ‘/ro{1,}t/p’ /etc/passwd    #打印出以r開頭至少有一個o的單詞的所在行
在這裏插入圖片描述







刪除行:

sed 'd' testfile1					#全刪
sed '3d' testfile1					#刪除第三行
sed '2,4d' testfile1				#刪除2-4行
sed '$d' testfile1					#刪除最後一行
sed '/^$/d' testfile1				#刪除空行
sed '/nologin$/d' /etc/passwd		#刪除/etc/passwd中以/nologin結尾的行
sed '/nologin$/!d' /etc/passwd		#“!”表示取反操作;
sed '/2/,/3/d' testfile2			#從第一個位置打開行刪除功能,到第二個位置關閉行刪除功能
sed '/1/,/3/d' testfile2

sed ‘d’ testfile1     #全刪
在這裏插入圖片描述
sed ‘3d’ testfile1             #刪除第三行
在這裏插入圖片描述
sed ‘2,4d’ testfile1            #刪除2-4行
在這裏插入圖片描述
sed ’ $ d’ testfile1            #刪除最後一行
在這裏插入圖片描述
sed ‘/^$ /d’ testfile2            #刪除空行
在這裏插入圖片描述
sed ‘/bash$ /d’ /etc/passwd       #刪除/etc/passwd中以/nologin結尾的行
在這裏插入圖片描述
sed ‘/bash$/!d’ /etc/passwd       #“!”表示取反操作;即除了以bash結尾的行,其他的全部刪除掉
在這裏插入圖片描述
sed ‘/1/,/4/d’ testfile2           #從第一個位置(1)打開行刪除功能,到第二個位置(4)關閉行刪除功能
在這裏插入圖片描述














替換:

行範圍 s/舊字符串/新字符串/替換標記

4種替換標記:
數字:表明新字符串將替換第幾處匹配的地方
g:表明新字符串將會替換所有匹配的地方
p:打印與替換命令匹配的行,與-n一起使用
w文件:將替換的結果寫到文件中
sed -n 's/root/admin/p' /etc/passwd 	 #把搜索出的root的所在行的第一個root替換成admin打印出來
sed -n 's/root/admin/2p' /etc/passwd	 #把搜索出的root的第二個root替換成admin打印出來
sed -n 's/root/admin/gp' /etc/passwd	 #把搜索出的所有的root替換成admin打印出來
sed -n 's/root//gp' /etc/passwd			 #把搜索出的所有的root替換成空格打印出來
sed -n '1,20 s/^/#/p' /etc/passwd		 #把1-20行的行首添加#打印出來
sed '/^root/ s/$/#/' /etc/passwd		 #把以root開頭的行搜索出來,在行尾添加#,打印出來
sed -f script.sed testfile2 			 #把腳本中的命令來執行testfile2
sed '1, 20w out.txt' /etc/passwd		 #把/etc/passwd的1-20行的內容存到out.txt中
sed '1,20 s/^/#/w out.txt' /etc/passwd	 #把/etc/passwd的1-20行內容在行首添加#,並存到out.txt中
sed -n 's/\/bin\/bash/\/bin\/csh/p' /etc/passwd #把/bin/bash替換成/bin/csh
sed -n 's!/bin/bash!/bin/csh!p' /etc/passwd		#使用“!”作爲字符串分隔符

sed -n ‘s/root/admin/p’ /etc/passwd #把搜索出的root所在行的第一個root替換成admin
在這裏插入圖片描述
sed -n ‘s/root/admin/2p’ /etc/passwd #把搜索出的root第二個root替換成admin
在這裏插入圖片描述
sed -n ‘s/root/admin/gp’ /etc/passwd #把搜索出的root所有的root替換成admin
在這裏插入圖片描述
sed -n ‘s/root//gp’ /etc/passwd #把搜索出的所有的root替換成空格打印出來
在這裏插入圖片描述
sed -n ‘1,20 s/^/#/p’ /etc/passwd #把1-20行的行首添加#打印出來
在這裏插入圖片描述
sed ‘/^root/ s/$/#/’ /etc/passwd #把以root開頭的行搜索出來,在行尾添加#,打印出來
在這裏插入圖片描述
sed ‘1, 5w out.txt’ /etc/passwd #把/etc/passwd的1-5行的內容存到out.txt中
在這裏插入圖片描述
sed ‘1,5 s/^/#/w out.txt’ /etc/passwd #在前五行的行首添加了’#’
在這裏插入圖片描述
sed -n ‘s!/bin/bash!/bin/csh!p’ /etc/passwd #把/bin/bash替換成/bin/csh
在這裏插入圖片描述
















插入:

sed '/45/c ABC' testfile2				#把45替換成ABC
sed '/45/ y/45/AB/' testfile2			#不常用,可忽略
sed '1,3a ABC' testfile2				#在第1行和第3行的下邊插入ABC
sed '1i ABC' testfile2					#在第1行的上邊插入ABC
sed '5r /etc/resolv.conf' testfile2	    #r--read 把etc/resolv.conf讀入到testfile2的第5行下邊
sed '/root/{H;d};$G' /etc/passwd		#將包含root的行剪切到末尾,H表示複製到剪切板,G表示粘貼到指定行後
sed '1,2H;3, 4G' /etc/ passwd			#將1、2行復制到3和4行的下面

二、awk

工作原理:

逐行讀取文本,默認以空格或tab鍵爲分隔符進行分隔,將分隔所得的各個字段保存到內建變量中,並按模式或者條件執行編輯命。
sed命令常用於一整行的處理,而awk比較傾向於將一行分成多個“字段"然後再進行處理。awk信息的讀入也是逐行讀取的,執行結果可以通過print的功能將字段數據打印顯示。在使用awk命令的過程中,可以使用邏輯操作符“&&”表示“與”、“||”表示“或”、“!”表示“非”;還可以進行簡單的數學運算,如+、-、*、/、%、^分別表示加、減、乘、除、取餘和乘方。

命令格式:
awk 選項 '模式或條件 {操作}' 文件1 文件2...
awk -f 腳本文件 文件1 文件2

awk常見的內建變量( 可直接用)如下所示: 
FS:列分割符。指定每行文本的字段分隔符,默認爲空格或製表位。與"-F"作用相同
NF:當前處理的行的字段個數。
NR: 當前處理的行的行號(序數)$0: 當前處理的行的整行內容。
$n: 當前處理行的第n個字段(第n列)。
FILENAME:被處理的文件名。
RS:行分隔符。awk從文件上讀取資料時,將根據RS的定義把資料切割成許多條記錄,而awk一次僅讀入一條記錄,以進行處理。預設值是'\n'

按行輸出文本:

awk '{print}' testfile2						 #輸出所有內容
awk '{print $0}' testfile2					 #輸出所有內容
awk 'NR==1,NR==3{print}' testfile2			 #輸出第1~3行內容.
awk '(NR>=1) && (NR<=3) {print}' testfile2	 #輸出第1~3行內容
awk 'NR==1||NR==3{print} ' testfile2		 #輸出第1行、第3行內容
awk '(NR%2)==1{print} ' testfile2		   	 #輸出所有奇數行的內容
awk '(NR%2)==0{print}' testfile2			 #輸出所有偶數行的內容
awk '/^root/{print}' /etc/passwd			 #輸出以root 開頭的行
awk '/nologin$/{print}' /etc/passwd 		 #輸出以nologin 結尾的行
awk 'BEGIN {x=0};/\/bin\/bash$/ {x++} ;END {print X}' /etc/passwd		#統計以/bin/bash結尾的行數,等同於grep -c
"/bin/bash$" /etc/ passwd

注:BEGIN模式表示,在處理指定的文本之前,需要先執行BEGIN模式中指定的動作; awk再 處理指定的文本,之後再執行END模式中指定的動作,END{ }語句塊中,往往會放入打印結果等語句

按字段輸出文本:

awk -F ":" ' {print $3}' /etc/passwd			#輸出每行中(以空格或製表位分隔)的第3個字段
awk -F ":" '{print $1,$3}' /etc/passwd		#輸出每行中的第1、3個字段
awk -F ":" '$3<5{print $1,$3}' /etc/passwd	#輸出第3個字段的值小於5的第1、3個字段內容
awk -F ":" '!($3<200) {print}' /etc/passwd	#輸出第3個字段的值不小於200的行
awk 'BEGIN {FS=":"};{if ($3>=200) {print}}' /etc/passwd #先處理完BEGIN的內容,再打印文本里面的內容
awk -F ":" '{max= ($3>$4)?$3:$4;{print max}}' /etc/passwd
#($3>$4)?$3:$4三元運算符,如果第3個字段的值大於第4個字段的值,則把第3個字段的值賦給max,否則第4個字段的值賦給max
awk -F ":" '{print NR,$0}' /etc/passwd		#輸出每行內容和行號,每處理完一條記錄,NR值加1
awk -F ":" '$7~"/bash"{print $1}' /etc/passw	#輸出以冒號分隔且第7個字段中包含/bash的行的第1個字段
awk -F ":" '($1~"root")&&(NF==7) {print $1,$2}' /etc/passwd #輸出第1個字段中包含root且有7個字段的行的第1、2個字段
awk -F ":" '($7!="/bin/bash") && ($7!="/sbin/nologin") {print}' /etc/passwd
#輸出第7個字段既不爲/bin/bash,也不爲/sbin/nologin的所有行

通過管道、雙引號調用Shell命令:

echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'
#統計以冒號分隔的文本段落數,END{}語句塊中,往往會放入打印結果等語句

awk -F: '/bash$/ {print | "wc -l"} ' /etc/passwd	#調用wc -l命令統計使用bash的用戶個數,等同grep-c "bash$" /etc/passwd

free -m | awk '/Mem:/ {print int ($3/($3+$4)*100) "g"} '		#查看當前內存使用百分比.
top -b -n 1 | grep Cpu | awk -F ',' '{print $4}' | awk '{print $1}'					
#查看當前CPU空閒率,(-b -n 1表示只需要1次的輸出結果)

date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
#顯示上次系統重啓時間,等同於uptime; second ago爲顯示多少秒前的時間,+"%F %H:%M:%S"等同於+"%Y-%m-%d%H:%M:%S"的時間格式

awk 'BEGIN {n=0; while ("w" | getline) n++ ; {print n-2}}' 	#調用w命令,並用來統計在線用戶數
awk 'BEGIN {"hostname" | getline ; {print $0}}'			#調用hostname, 並輸出當前的主機名

seq 10 | awk '{getline; print $0}'
seq 10 | awk '{print $0; getline}'

注:當getline左右無重定向符“<”或“|”時,awk首先讀取到了第一行,就是1,然後getline,就得到了1下面的第二行,就是2,因爲getline之後,awk會改變對應的NF,NR,FNR和$0等內部變量,所以此時的$0的值就不再是1,而是2了,然後將它打印出來。
當getline左右有重定向符“<”或“|”時,getline則作用於定向輸入文件,由於該文件是剛打開,並沒有被awk讀入一行,只是getline讀入,那麼getline返回的是該文件的第一行,而不是隔行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章