正則表達式與其應用
數據處理工具:awk ,sed
正則表達式基本上是一種“表示法”,只要工具程序支持這種表示法,那麼該工具程序就可以用來作爲正則表達式的字符串處理只用。例如vi,grep,awk,sed等工具
正則表達式特殊符號
語系對應正在表達式也會存在影響。比如
LANG=C時:0 1 2 3 4 … A B C D ..Z a b c d ..z
LANG=ZH_CN時:0 1 2 3 4 …a A b B c C d D …….
因此[a-z]當C語系時代表的意義是獲取小寫字母。在ZH_CN語系時代表的意義就是獲取字母(大寫與小寫)
爲了避免數字和字母的選取錯誤,正則表達式採用特殊符號來代表
[:alnum:]:代表英文大小寫字符及數字。A-Z a-z 0-9
[:alpha:]:代表英文大小寫字符 A-Z a-z
[:blank:]:代表空格與TAB鍵
[:cntrl:]:代表鍵盤上的控制按鍵 CR,LF,TAB,DEL等
[:digit:]:代表數據 0-9
[:graph:]:代表除了空格與TAB鍵的其他所有按鍵
[:lower:]:代表小寫字符
[:upper:]:代表大寫字符
[:print:]:代表任何可以被打印出來了的字符
[:punct:]:代表標點符號字符
[:space:]:代表會產生的空白的字符如TAB空格 CR
[:xdigit:]:代表十六進制的數字類型 0-9 A-F a-f
舉例
[root@localhost ~]# cat xargsfile |grep -n '[[:upper:]]'
2:FRA
4:AWEE
基礎正則表達式字符
字符 | 意義與範例 |
^word | 意義:查找以word爲行首的數據 舉例:查找以#開始的那一行 gerp ‘^#’ file.txt |
Word$ | 意義:查找以word爲行尾的數據 舉例:查找以#爲結尾的那一行 grep‘#$’ file.txt |
. | 意義:代表一定有一個任意字符 舉例查找字符串eae,ebe e e,ee之間一定有一個字符,空格也算字符 G rep ‘e.e’ file.txt |
* | 意義:重複0個到無窮個前一個字符 舉例:查找含有es ess esss等的字符串 grep ‘ess*’ file.txt |
[] | 意義:從字符集合中找出想要選取的字符 舉例:查找含有gl或gd的那一行 grep ‘g[ld]’ file.txt |
[n1-n2] | 意義:從字符集合裏找出想要選取的字符範圍 舉例:查找含有任意數字的哪一行 grep ‘[0-9]’ file.txt |
[^] | 意義:從字符集合中找處不要的字符或範圍 舉例:查找不含大寫字母的那一行 grep ‘[^A-Z]’ file.txt |
\{n,m\} | 意義:連續n個到m個的前一個字符,如\{n\}則是連續n個前一個字符,如\{n,\}則是連續n個以上前一個字符 舉例1:查找g與g之間包含2個到3個o的字符串如:goog gooog grep ‘\{2,\3}’ file.txt 舉例2:查找g與g之間包含2個o的字符串如:goog grep ‘\{2\}’ file.txt 舉例3:查找g與g之間包含3個及以上o的字符串如:gooog,gooood,goo….od grep ‘\{3,\}’ file.txt |
擴展正則表達式
字符 | 意義與範例 |
+ | 意義:重複一個或一個以上的字符 舉例:查找god,good,good等字符串 egrep ‘go+d’ file.txt |
? | 意義:0個過1個前一個字符 舉例:查找gd god egrep ‘go?d’ file.txt |
| | 意義:用或的方式找出數個字符串 舉例:找出my ,own egrep ‘my|own’ file.txt |
() | 意義:找出“組“的字符串 舉例:找出good 或glad egrep ‘g(oo|la)d’ file.txt |
()+ | 意義:多個重複組的判別 舉例:找出Axy123123123C egrep ‘Axy(123)+C’ file.txt |
說明:如grep需要使用擴展正則表達式,可使用grep –e或egrep
sed
sed本身是一個也是一個管道命令。可以分析輸入數據流,還可以將數據進行替換,刪除,選去等操作
sed與tr的區別
tr操作的單元是字符,它針對字符進行刪除和替換
sed操作單元的是行,它針對行進行刪除和替換
sed與vim的區別
sed是管道命令它修改只是輸入數據流,並不會修改文件本身。雖然sed也可以直接修改文件,但是不需要打開文件,對於大文件來說很有幫助
vim是文本編輯器,它修改的是文件本身
語法:sed [-nefr] ‘動作’
選項與參數:
-n:silent模式,只將sed處理過的內容顯示i出來
-e:設置多個sed動作
-f filename: 文件內記錄sed腳本scipt
-r:sed支持的擴展正則表達式語法(默認是基礎正則表達式)
-i:直接修改讀取文件內容,而不是屏幕輸出
動作:n1,n2function
n1,n2不一定存在
function:
a:新增,a後面接字符串,這些字符在當前的下一行顯示
c:替換,c後面接字符串,這些字符替換n1-n2之間的行
d:刪除,刪除n1-n2之間的行
i:添加,i後面接字符串,這些字符在當前的上一行顯示
p: 打印,打印n1~n2行之間的數據
s: 替換以關鍵字形式替換,並不是替換整行. sed ‘s/舊字符串/新字符串/g’’
舉例:
[root@localhost ~]# cat sedfile |sed -n 'p' =>查詢所有內容 line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9 line 10 [root@localhost ~]# cat sedfile |sed -n '1,4p'=>查詢1~4內容 line 1 line 2 line 3 line 4 [root@localhost ~]# cat sedfile |sed '2a new line'|sed -n '1,5p' =>在第2行下添加新的一行 line 1 line 2 new line line 3 line 4 [root@localhost ~]# cat sedfile |sed '3d'|sed -n '1,4p' =>刪除第3行 line 1 line 2 line 4 line 5 [root@localhost ~]# cat sedfile |sed '2i insert line'|sed -n '1,5p' =>在第2行上添加新的一行 line 1 insert line line 2 line 3 line 4 [root@localhost ~]# cat sedfile |sed '2,3c replace line'|sed -n '1,3p' =>替換2~3行 line 1 replace line line 4 [root@localhost ~]# cat sedfile |sed '1,3s/ne/NEL/g'|sed -n '1,6p' =>用NEL替換2~3行的ne liNEL 1 liNEL 2 liNEL 3 line 4 line 5 line 6
舉例2:使用sed直接修改文件
[root@localhost ~]# sed -i '$a this is line' sedfile ;cat sedfile|tail -n 2 line 10 this is line
awk
(awk功能很強大,這裏只是功能介紹性說明)
Awk 是一個數據處理工具,相比sed作用於一整行的處理,awk則將一行分爲數個“字段”處理
awk的處理流程
1.讀入第一行,並將第一行的數據填入$0,$1,$2……等變量中
2.依據條件類型的限制,判斷是否需要後面的動作
3.做完所有的動作與條件類型
4.若還有後續的行的數據,則重複1-3步驟
語法:awk ‘條件類型1 {動作1}條件類型2 {動作2}……’ filename
說明:
1.awk默認用空格或tab來分割一行數據,並將數據填充到$1,$2..中
如:root pts1 192這一行, $1=root $2=pts1.
2. awk後方語句中非變量需使用雙引號來定義,變量可以直接使用
awk內置變量
變量 | 描述 |
$n | 當前記錄的第n個字段,字段間由FS分隔。 |
$0 | 完整的輸入記錄。 |
ARGC | 命令行參數的數目。 |
ARGIND | 命令行中當前文件的位置(從0開始算)。 |
ARGV | 包含命令行參數的數組。 |
CONVFMT | 數字轉換格式(默認值爲%.6g) |
ENVIRON | 環境變量關聯數組。 |
ERRNO | 最後一個系統錯誤的描述。 |
FIELDWIDTHS | 字段寬度列表(用空格鍵分隔)。 |
FILENAME | 當前文件名。 |
FNR | 同NR,但相對於當前文件。 |
FS | 字段分隔符(默認是任何空格)。 |
IGNORECASE | 如果爲真,則進行忽略大小寫的匹配。 |
NF | 當前記錄中的字段數。 |
NR | 當前記錄數。 |
OFMT | 數字的輸出格式(默認值是%.6g)。 |
OFS | 輸出字段分隔符(默認值是一個空格)。 |
ORS | 輸出記錄分隔符(默認值是一個換行符)。 |
RLENGTH | 由match函數所匹配的字符串的長度。 |
RS | 記錄分隔符(默認是一個換行符)。 |
RSTART | 由match函數所匹配的字符串的第一個位置。 |
SUBSEP | 數組下標分隔符(默認值是\034)。 |
awk運算符
運算符 | 描述 |
= += -= *= /= %= ^= **= | 賦值 |
?: | C條件表達式 |
|| | 邏輯或 |
&& | 邏輯與 |
~ ~! | 匹配正則表達式和不匹配正則表達式 |
< <= > >= != == | 關係運算符 |
空格 | 連接 |
+ - | 加,減 |
* / & | 乘,除與求餘 |
+ - ! | 一元加,減和邏輯非 |
^ *** | 求冪 |
++ -- | 增加或減少,作爲前綴或後綴 |
$ | 字段引用 |
in | 數組成員 |
舉例1:查看$1 NR NF
[root@bogon ~]# last -n 5 | awk '{print $1 "\t lines: " NR "\t cols: "NF }' root lines: 1 cols: 10 root lines: 2 cols: 9 root lines: 3 cols: 9 reboot lines: 4 cols: 9 root lines: 5 cols: 10
舉例2:帶有條件的,僅輸出$1==root的數據
[root@bogon ~]# last -n 5 | awk '$1=="root" {print $1 "\t lines: " NR "\t cols: "NF }' root lines: 1 cols: 10 root lines: 2 cols: 9 root lines: 3 cols: 9 root lines: 5 cols: 10
awk關鍵字
BEGIN
BEGIN關鍵字作用是預設,在讀如第一行前面就執行BEGIN後面的動作
比如每一行默認分割方式是空格或是TAB,所以我們可以設置FS來改變分割符,但是此時第一行數據已經讀取分析完畢,列信息已經存在$1,$2..中,改變只能從第2行開始。
舉例:
[root@bogon ~]# cat /etc/passwd|head -n 5 |awk 'BEGIN {FS=":"} NR=="1" {print"UID\tGID"} NR>="1" {print $1 "\t" $3}' UID GID root 0 bin 1 daemon 2 adm 3 lp 4
舉例2 計算數據(num1+num2)
數據文件 month:num1:num2 1:100:150 2:200:250 3:300:350 4:400:450 5:500:550 6:600:650 [root@bogon ~]# cat cal.file |awk 'BEGIN {FS=":"} NR=="1" {print$1"\t"$2"\t"$3"\ttotal"} NR>"1" {print$1"\t"$2"\t"$3"\t"$2+$3}'
month num1 num2 total 1 100 150 250 2 200 250 450 3 300 350 650 4 400 450 850 5 500 550 1050 6 600 650 1250
END
END操作將在掃描完全部的輸入之後執行
舉例:
[root@bogon ~]# cat cal.file |awk 'BEGIN {FS=":"} NR=="1" {print$1"\t"$2"\t"$3"\ttotal"} NR>"1" {print$1"\t"$2"\t"$3"\t"$2+$3} END {print "sum"}' month num1 num2 total 1 100 150 250 2 200 250 450 3 300 350 650 4 400 450 850 5 500 550 1050 6 600 650 1250 sum