1. 程式人生 > 實用技巧 >shell指令碼之grep,sed,awk

shell指令碼之grep,sed,awk

一、grep

強大的全域性文字搜尋命令,並能將匹配到的文字按行列印
支援正則表達

用法

grep [OPTIONS] PATTERN [FILE]  

或者
cat FILE|grep [OPTIONS] PATTERN 

1 常用的OPTIONS

-c    統計匹配到的行數  
-i    匹配時不區分大小寫
-n    顯示匹配行所在行號
-o    只顯示匹配到的字串
-v    取反,方向匹配,不匹配關鍵字的行
-E    開啟擴充套件的正則表示式
-A n  顯示匹配的所在的行及其後n行
-B n  顯示匹配的所在的行及其前n行
-C n  顯示匹配的所在的行及其前後各n行

2 PATTERN部分

主要為基本正則表示式

2.1 基本字元組

.          匹配除換行符外的任意一個字元
.*         匹配所有內容
[abc]      匹配abc三個字元中的任意一個字元
[^abc]     匹配不包含abc三個字元中的任意一個字元(與[abc]相反)

2.2特殊字元組

[A-Za-z] 等價於 [[:alpha:]]       匹配任意字母字元,不管大小寫
[0-9] 等價於 [[:digit:]]          匹配任意數字字元
[A-Za-z0-9] 等價於 [[:alnum:]]    匹配任意字母數字字元
tab,space 等空白字元 [[:space:]]   匹配任意空格符
[A
-Z] 等價於 [[:upper:]] 匹配任意大寫字目字元 [a-z] 等價於 [[:lower:]] 匹配任意小寫字母字元 [[:punct:]] 匹配標點符號

2.3 出現次數

*        前面的字元出現任意次,包括0次
\?       前面的字元出現0次或1次,\為轉義符
\+       前面的字元至少出現一次
\{m\}    前面的字元出現m次,\為轉義符
\{m,\}   前面的字元至少出現m次,\為轉義符
\{m,n\}  前面的字元至少出現m次,至多n次,\為轉義符

2.4位置錨定

^    錨定行首,即以什麼開頭
$    錨定行尾,即以什麼結尾
^$ 空白行 \b 錨定詞首或詞尾,前面為詞首,如"\bwho"匹配到whoami,後面為詞尾,如"who\b"會匹配到iswho \< 錨定單詞的詞首 \> 錨定單詞的詞尾 \B 與\b作用相反

2.5 ()分組引用

\(str\)  用()將str作為一個整體方便後面引用,第一個()為$1,以此類推
\1          引用第1個左括號及其對應的右括號所匹配的內容
\n          引用第n個左括號及其對應的右括號所匹配的內容

3 擴充套件的正則表示式

即OPTIONS的-E選項

字元組和特殊字元組與基本正則表示式一樣

次數和位置錨定 沒有轉義符,其他的和基本正則表示式一樣
分組引用 (string) \
1 \n

二、sed

非互動流式文字編輯器,可以對文字檔案進行增、刪、改、查等操作
支援正則表示式

用法

sed OPTIONS sed命令 FILE

sed OPTIONS -f 包含sed命令的FILE FILE

1 OPTIONS

-e  用於進行多重編輯,即同時有多個sed命令時使用,即sed -e sed命令 -e sed命令 FILE
-f  後接包含sed命令的FILE
-i  直接修改FILE內容,不加-i時只是預覽,不會修改FILE內容
-n  取消預設的輸出,只顯示處理過的行,sed預設輸出FILE的所有內容
-r  使用擴充套件正則表示式,預設只識別基本正則表示式

2 sed命令

a   新增,指定行後方加入新行
i   新增,指定行前方加入新行
c   替換行,將指定行的內容全部替換
d   刪除
p   將指定內容列印到終端上,通常與OPTIONS -n 一起用
s   替換指定字串

3 基本使用

3.1 顯示

若str包含變數,請使用雙引號("")

sed -n 'Np;Mp;Xp' FILE 顯示行號為N,M,X的多行 sed -n '$p' FILE 顯示最後一行 sed -n '/str/p'FILE 顯示包括str的所有行 sed -n 'N,Mp' FILE 顯示第N行到第M行

3.2 刪除

以下命令只是預覽,不會真正修改檔案內容,若下行要修改檔案內容,請使用sed -i 
若str包含變數,請使用雙引號("") sed
'N,Md' FILE 顯示刪除第N行到第M行剩下的內容 sed '/str1/,/str2/d’ FILE 顯示刪除包含str1的行到包含str2的行剩下內容 sed '/str/,Nd' FILE 顯示刪除包含strt的行到第N行剩下的內容 sed '/str/d' FILE 顯示刪除包含str的行剩下的內容 sed '/^$/d' FILE 顯示刪除空白行剩下的內容

3.3 增加

以下命令會真正修改檔案內容,請謹慎使用
若str包含變數,請使用雙引號("") sed
-i 'Na str' FILE 第N行後增加一行字元 sed -i 'Na str1\nstr2' FILE 第N行後增加二行字元 sed -i 'N,Ma str' FILE 第N行到第M行的每行後都增加一行字元 sed -i 'Ni str' FILE 第N行前增加一行字元 sed -i 'Ni str1\nstr2' FILE 第N行前增加二行字元 sed -i 'N,Mi str' FILE 第N行到第M行的每行前都增加一行字元

3.4 替換

以下命令會真正修改檔案內容,請謹慎使用
若str包含變數,請使用雙引號("")
sed
-i 'Nc str' FILE 將第N行的內容替換為str sed -i 'N,Mc str' FILE 將第N行到第M行的內容替換為str sed -i 's/str1/newstr/g' FILE 將所有的str1替換為newstr sed -i 's/str1/newstr2/gw FILE1' FILE2 將處理過的行另存到檔案1 sed -i 's/str1/newstr/g' FILE2 >FILE1 將處理後的內容重定向至檔案1

三、awk
文字處理工具,以欄位為單位進行處理
支援正則表示式

用法

awk [OPTIONS] '[pattern] {action}' FILE

cat FILE |awk [OPTIONS] '[pattern] {action}'

1 awk內建變數

1.1 欄位和分隔符變數

$0  滿足條件的所有文字內容
$1  以FS分隔符隔開的第一列內容
$2  以分隔符隔開的第二列內容
$n  以分隔符隔開的第n列內容

FS     指定欄位(列)分隔符,預設空格 
RS     指定處理時的行分隔符,遇到該符號就是一行,預設換行符
OFS    指定輸出的欄位(列)分隔符,預設空格
ORS    指定輸出的行分隔符,行以該符號結尾,預設換行符

1.2 資料變數

ARGC  命令列的引數個數
ARGV  命令列所有引數組成的陣列
ARGIND  被處理檔案在ARGV中的位置

NF    當前行的欄位個數,即列數
NR    當前行的行號
FNR    處理多個檔案時,當前行在本檔案中的行號

FIELNAME 被處理的檔名

IGNORECASE    如果為真,則進行忽略大小寫的匹配
CONVFMT    數字轉換格式 %.6g
ENVIRON    UNIX環境變數
ERRNO    UNIX系統錯誤訊息
FIELDWIDTHS    輸入欄位寬度的空白分隔字串
OFMT    數字的輸出格式 %.6g
RSTART    被匹配函式匹配的字串首
RLENGTH    被匹配函式匹配的字串長度
SUBSEP    \034

2 OPTIONS

-F  指定分隔符,預設為空格,包括一個或多個空格鍵或tab鍵
-v  定義變數和初始值,可以在 pattern {action}使用
-f  後接包含pattern {action}的檔案

3 [pattern] {action}

3.1 pattern

1) BEGIN和END

BEGIN    在awk尚未讀取任何資料之前執行,只執行一次
END        在awk處理完文字所有資料後執行,只執行一次

其中
BEGIN中定義的變數只能在當前的BEGIN中使用
END中定義的變數只能在當前的END中使用


示例 awk
'BEGIN {print "ready start!"} /a/{print $0}' FILE 先輸出ready start!,再輸出包含字元'a'的整行內容 awk '/a/{print $0} END {print "ready start!"}' FILE 先輸出包含字元'a'的整行內容,再輸出ready start!

2) 關係運算符

>
<
>=
<=
==
!=

示例
awk 'NR>2 {print $0 }' FILE
輸出行號大於2的所有行

awk 'NR<2 {print $0 }' FILE
輸出行號小於2的所有行

awk 'NR>=2 {print $0 }' FILE
輸出行號大於等於2的所有行

awk 'NR<=2 {print $0 }' FILE
輸出行號小於等於2的所有行

awk 'NR==2 {print $0 }' FILE
輸出行號等於2的行

awk 'NR!=2 {print $0 }' FILE
輸出行號不等於2得所有行

awk -F ',' '$1==10 && $2==9 {print $0 }' FILE
輸出第一列為10,第二列為9的行的內容

awk -F ',' '$1==10 || $2==9 {print $0 }' FILE
輸出第一列為10或者第二列為9的行的內容

3)匹配操作符

匹配操作符
str1 ~ /str2/ 
str1 !~ /str2/

其中
str2可以是正則表示式

示例 
awk -F ',' '$1 ~ /^asd/ {print $0 }'  FILE
輸出第一列以asd開頭的行的內容

awk -F ',' '$1 !~ /^asd/ {print $0 }'  FILE
排除第一列以asd開頭的行

4)正則表示式

/str/  匹配含有str的內容

示例
awk -F ',' '/^asd/ {print $0 }'  FILE
輸出以asd開頭所有行的內容

3.2 {action}

1)格式化輸出printf

基本很少使用,使用print頻率極高

c   以ASCII碼顯示
d   以整數顯示
i   以整數顯示
e   以科學計數法顯示
f   以浮點數顯示
g   以科學計數法或浮點數顯示
o   以八進位制顯示
s   以字串顯示
x   以十六進位制顯示
X   以十六進位制顯示,但用大寫字母A~F

awk -F ',' '$1 ~ /^[0-9][0-9]*/ {printf "%e,%f\n",$1,$3 }'  FILE
輸出第一列全是數字的第一列,第三列,並以科學計數法顯示第一列,浮點數顯示第三列

注意:
prtinf必須有\n,否則不會換行

2)結構化流程控制

A if語句

awk -F ',' '{if(NR==2 || $1 ~ /a/) print $0}' FILE
輸出第二行或者第一個欄位包含字元a的行

awk -F ',' '{if(NR==2 || $1 ~ /a/) print $0;else print NR,$1}' FILE
輸出第二行或者第一個欄位包含字元a的行,以及不滿足條件的行號和第一列

B wihle語句

awk -F ',' '{total=0;i=1; while (i<4){total+=$i;i++} avg=total/3;print avg }'  FILE
輸出前三列的平均值

其中
$i表示第幾列資料

C do-while語句

awk -F ',' '{total=0;i=1; do {total+=$i;i++} while (i<5);print total }'  FILE
輸出前四列之和

其中
$i表示第幾列資料

D for語句

awk -F ',' '{total=0; for(i=1;i<5;i++) {total+=$i};print total }'  FILE
輸出前四列之和

其中
$i表示第幾列資料