linux 下的 正則表達式(awk,sed,awk)學習


轉自:https://www.cnblogs.com/menglingqian/p/6783527.html
一、正則表達式:
正則表達式(或稱Regular Expression,簡稱RE)就是由普通字符(例如字符 a 到 z)以及特殊字符(稱為元字符)組成的文字模式。 該模式描述在查找文字主體時待匹配的一個或多個字符串。 正則表達式作為一個模板,將某個字符模式與所搜索的字符串進行匹配。簡單的說,正則表示式就是處理字符串的方法,它是以行為單位來進行字符串的處理行為, 正則表示式通過一些特殊符號的輔助,可以讓使用者輕易的達到搜尋/刪除/取代某特定字符串的處理程序。vim、grep、find、awk、sed等命令都支持正則表達式。 常用正則表達式: 1、.代表任意單個字符, 如:/l..e/與包含一個l,后跟兩個字符,然后跟一個e的行相匹配 ? 匹配零個或一個字符。如:'gr?p'匹配gr后跟一個或沒有字符,然后是p的行 2、^代表行的開始。 ^love 如:與所有love開頭的行匹配 3、$代表行的結束。love$ 如:與所有love結尾的行匹配 那么‘^$’ 就表示空行 4、[…]匹配括號中的字符之一 [abc] 匹配單個字符a或b或c [123] 匹配單個字符1或2或3 [a-z] 匹配小寫字母a-z之一 [a-zA-Z] 匹配任意英文字母之一 [0-9a-zA-Z]匹配任意英文字母或數字之一 注意:上面標紅色的單個和之一,不管[]里面多復雜,它的結果都是一個字符! 可以用^標記做[]內的前綴,表示除[]內的字符之外的字符。比如 搜索oo前沒有g的字符串的行. 應用 '[^g]oo' 作搜索字符串,^符號如果出現在[]的起始位置表示否定,但是在[]的其他位置是普通字符。[^ab^c] 匹配b或^或c或不是a的任意單個字符 5、* 用於修飾前導字符,表示前導字符出現0次或任意多次 如:'a*grep'匹配所有0個或多個a后緊跟grep的行。“.*”表示任意字符串 6、\? 用於修飾前導字符,表示前導字符出現0或1次 a\? 匹配0或1個a 7、\+ 用於修飾前導字符,表示前導字符出現1或多次 a\+ 匹配1或多個a 8、\{n,m\} 用於修飾前導字符,表示前導字符出現n至m次 (n和m都是整數,且n<m) a\{3,5\} 匹配3至5個連續的a \{n,m\}還有其他幾種形式: \{n\} 連續的n個前導字符 \{n,\} 連續的至少n個前導字符 9、\ 用於轉義緊跟其后的單個特殊字符,使該特殊字符成為普通字符 如:^\.[0-9][0-9] 對以一個句點和兩個數字開始 例如: a* 匹配連續的任意(也包括0)個a a\? 匹配0或1個a a\+ 匹配1或多個a a\{3,5\} 匹配3至5個連續的a \.* 匹配0或多個連續的. \.表示普通字符句點 10、|表示或 如: a|b|c 匹配a或b或c。如:grep|sed匹配grep或sed 11、(),將部分內容合成一個單位組,比如 要搜索 glad 或 good 可以如下 'g(la|oo)d' 綜合舉例1: 1 Christian Scott lives here and will put on a Christmas party. 2 There are around 30 to 35 people invited. 3 They are: 4 Tom 5 Dan 6 Rhonda Savage 7 Nicky and Kimerly. 8 Steve, Suzanne, Ginger and Larry. ^[A-Z]..$ 搜索行以A至Z的一個字母開頭,然后跟兩個任意字母,然后跟一個換行符的行。將找到第5行。 ^[A-Z][a-z]*3[0-5] 搜索以一個大寫字母開頭,后跟0個或多個小寫字母,再跟數字3,再跟0—5之間的一個數字。無法找到匹配行(改成^[A-Z][a-z]*.*3[0-5]可找到第2行) ^ *[A-Z][a-z][a-z]$ 搜索以0個或多個空格開頭,跟一個大寫字母,兩個小寫字母和一個換車符。將找到第4行的TOM(整行匹配)和第5行。注意,*前面有一個空格。 ^[A-Za-z]*[^,][A-Za-z]*$ 將查找以0個或多個大寫或小寫字母開頭,不跟逗號,然后跟0個或多個大寫或小寫字母,然后跟一個換車符。將找到第4和5行。 綜合舉例2: # ls -l /bin | grep '^...s' 上面的命令是用來查找suid文件的; # ls -lR /usr | grep '^...s..s' 上面的命令是用來查找suid和guid的。 二、grep命令的用法 grep (global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來. 參數: 1. -A NUM,--after-context=NUM 除了列出符合行之外,並且列出后NUM行。 如: $ grep –A 1 panda file (從file中搜尋有panda樣式的行,並顯示該行的后1行) 2. -B NUM,--before-context=NUM 與 -A NUM 相對,但這此參數是顯示除符合行之外並顯示在它之前的NUM行。如: (從file中搜尋有panda樣式的行,並顯示該行的前1行) $ grep -B 1 panda file 3、 -C [NUM], -NUM, --context[=NUM] 列出符合行之外並列出上下各NUM行,默認值是2。 如: (列出file中除包含panda樣式的行外並列出其上下2行)(若要改變默認值,直接改變NUM即可) $ grep -C[NUM] panda file 4、 -c, --count 不顯示符合樣式行,只顯示符合的總行數。若再加上-v,--invert-match,參數顯示不符合的總行數 5、-i,--ignore-case 忽略大小寫差別 6、-n,--line-number 在匹配的行前面打印行號 7、-v,--revert-match 反檢索,只顯示不匹配的行 8、精確匹配: 例如在抽取字符串“ 48”,返回結果包含諸如484和483等包含“48”的其他字符串,實際上應精確抽取只包含48的各行。 使用grep抽取精確匹配的一種有效方式是在抽取字符串后加\>。假定現在精確抽取48, 方法如下: #grep '48\>' filename 9、-s 不顯示不存在或無匹配文本的錯誤信息 如:執行命令grep "root" /etc/password,因為password文件不存在,所以在屏幕上輸出錯誤信息,若使用grep命令-s開關,可屏蔽錯誤信息 要用好grep這個工具,其實就是要寫好正則表達式,所以這里不對grep的所有功能進行實例講解,只列幾個例子,講解一個正則表達式的寫法。 $ ls -l | grep '^d' 通過管道過濾ls -l輸出的內容,只顯示以d開頭的行。 $ grep 'test' d* 顯示所有以d開頭的文件中包含test的行。 $ grep 'test' aa bb cc 顯示在aa,bb,cc文件中匹配test的行。 $ grep '[a-z]\{5,\}' aa 顯示所有包含每個字符串至少有5個連續小寫字符的字符串的行。 $grep ‘t[a|e]st’ filename 顯示包含test或tast的所有行。 $grep '\.$' filename 顯示以.為結尾的所有行。 三、sed命令的用法 sed是一種在線編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接着用sed命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。接着處理下一行,這樣不斷重復,直到文件末尾。文件內容並沒有改變,除非你使用重定向存儲輸出。 sed的基本命令: 1.替換: s命令 1.1 基本用法 如: sed 's/day/night/' <old >new 該例子將文件 old 中的每一行第一次出現的 day 替換成 night, 將結果輸出到文件 new s " 替換 " 命令 /../../ 分割符 (Delimiter) day 搜索字符串 night 替換字符串 其實 , 分割符 "/" 可以用別的符號代替 , 比如 ",", "|" 等 . 如:sed 's/\/usr\/local\/bin/\/common\/bin/'<old >new 等價於 sed 's_/usr/local/bin_/common/bin_' <old >new 顯然 , 此時用 "_" 作分割符比 "/" 好得多 1.2 用 & 表示匹配的字符串 有時可能會想在匹配到的字符串周圍或附近加上一些字符 . 如: sed 's/abc/(abc)/' <old >new 該例子在找到的 abc 前后加上括號 . 該例子還可以寫成 sed 's/abc/(&)/' <old >new 下面是更復雜的例子 : sed 's/[a-z]*/(&)/' <old >new sed 默認只替換搜索字符串的第一次出現 , 利用 /g 可以替換搜索字符串所有 $ sed 's/test/mytest/g' example-----在整行范圍內把test替換為mytest。如果沒有g標記,則只有每行第一個匹配的test被替換成mytest。 $ sed 's/^192.168.0.1/&localhost/' example-----&符號表示替換字符串中被找到的部份。所有以192.168.0.1開頭的行都會被替換成它自已加 localhost,變成192.168.0.1localhost。 $ sed 's#10#100#g' example-----不論什么字符,緊跟着s命令的都被認為是新的分隔符,所以,“#”在這里是分隔符,代替了默認的“/”分隔符。表示把所有10替換成100。 如果需要對同一文件或行作多次修改,可以使用 "-e" 選項

取得eth0網卡IP地址:

2.刪除行:d命令

從某文件中刪除包含 "how" 的所有行

將/etc/passwd的內容顯示並找印行號,同時將2~5刪除

附:nl命令在linux系統中用來計算文件中行號。nl 可以將輸出的文件內容自動的加上行號

如果只要刪除第2行,可以使用nl /etc/passwd | sed '2d' 來達成,至於若是要刪除第 3 到最后一行,則是nl /etc/passwd | sed '3,$d'即可。

3.增加行:a命令(在指定的行后新增)或i命令(在指定的行前新增)

a的后面可以接字符串,而這些字符串會在新的一行出現

在/etc/passwd的第二行后增加“XXXXX”字樣的新行

在/etc/passwd的第二行前增加“XXXXX”字樣的新行

如果要同時新增多行,則每行之間要用反斜杠\來進行新行的添加

4、取代行:c命令

c的后面可以接字符串,這些字符串可以取代n1,n2之間的行

5、打印:p命令

sed '/north/p' datafile 默認輸出所有行,找到north的行重復打印

 

sed  –n '/north/p' datafile 禁止默認輸出,只打印找到north的行

 

nl /etc/passwd | sed -n '5,7p' 僅列出/etc/passwd文件中的第5~7行內容

 

注:sed 的-i選項可以直接修改文件中的內容

6.擴展:

調用sed有三種方式:

l  在命令行鍵入命令

l  將sed命令插入腳本文件,然后調用sed

l  將sed命令插入腳本文件,並使sed腳本可執行。

A、 使用sed命令行格式為:

sed [選項] sed命令 輸入文件。

記住在命令行使用sed命令時,實際命令要加單引號。sed也允許加雙引號。

 

B、使用sed腳本文件,格式為:

sed [選項] -f sed腳本文件  輸入文件

 

C、要使用第一行具有sed命令解釋器的sed腳本文件,其格式為:

sed腳本文件 [選項]  輸入文件

 

不管是使用shell命令行方式或腳本文件方式,如果沒有指定輸入文件, sed從標准輸入中接受輸入,一般是鍵盤或重定向結果。

 

sed選項如下:

-f, --filer=script-file 引導sed腳本文件名

 

五、awk命令:

awk也是一個數據處理工具!相較於 sed 常常作用於一整個行的處理, awk 則比較傾向於一行當中分成數個字段來處理。

 

.awk語言的最基本功能是在文件或字符串中基於指定規則來分解抽取信息,也可以基於指定的規則來輸出數據。

 

有三種方式調用awk

 

1.命令行方式

awk  [-F field-separator]  'commands'  input-files

其中,[-F域分隔符]是可選的,因為awk使用空格或tab鍵作為缺省的域分隔符,因此如果要瀏覽域間有空格的文本,不必指定這個選項,如果要瀏覽諸如passwd文件,此文件各域以冒號作為分隔符,則必須指明-F選項,如:awk -F: 'commands' input-file。

commands 是真正awk命令, input-files 是待處理的文件。

輸出結果如下,字段以:分割,取到每行的第一個字段

iput_files可以是多於一個文件的文件列表,awk將按順序處理列表中的每個文件。

在awk中,文件的每一行中,由域分隔符分開的每一項稱為一個域。通常,在不指名-F域分隔符的情況下,默認的域分隔符是空格或tab鍵。

 

2.shell腳本方式

將所有的awk命令插入一個文件,並使awk程序可執行,然后awk命令解釋器作為腳本的首行,以便通過鍵入腳本名稱來調用。

相當於shell腳本首行的:#!/bin/sh可以換成:#!/bin/awk

 

3.將所有的awk命令插入一個單獨文件,然后調用:

Awk   -f   awk-script-file         input-files

其中,-f選項加載awk-script-file中的awk腳本,input-files跟上面的是一樣的。

 

awk的模式和動作

 

任何awk語句都由模式和動作組成(awk_pattern { actions })。
在一個awk腳本中可能有許多語句。

模式部分決定動作語句何時觸發及觸發事件。處理即對數據進行的操作。如果省略模式部分,動作將時刻保持執行狀態。即省略時不對輸入記錄進行匹配比較就執行相應的actions。

 

模式可以是任何條件語句或正則表達式等。awk_pattern可以是以下幾種類型:

 

1) 正則表達式用作awk_pattern: /regexp/

例如:awk '/ ^[a-z]/' input_file

2) 布爾表達式用作awk_pattern,表達式成立時,觸發相應的actions執行。

① 表達式中可以使用變量(如字段變量$1,$2等)和/regexp/

② 布爾表達式中的操作符:

 

關系操作符: < > <= >= == !=
匹配操作符: value ~ /regexp/ 如果value匹配/regexp/,則返回真
value !~ /regexp/ 如果value不匹配/regexp/,則返回真
例如: awk '$2 > 10 {print "ok"}' input_file
      awk '$3 ~ /^d/ {print "ok"}' input_file

③ &&(與) 和 ||(或) 可以連接兩個/regexp/或者布爾表達式,構成混合表達式。!(非) 可以用於布爾表達式或者/regexp/之前。

 

例如: awk '($1 < 10 ) && ($2 > 10) {print "ok"}' input_file
      awk '/^d/ || /x$/ {print "ok"}' input_file

模式包括兩個特殊字段 BEGIN和END。使用BEGIN語句設置計數和打印頭。BEGIN語句使用在任何文本瀏覽動作之前,之后文本瀏覽動作依據輸入文本開始執行。END語句用來在awk完成文本瀏覽動作后打印輸出文本總數和結尾狀態標志。

 

實際動作在大括號{ }內指明。動作大多數用來打印,但是還有些更長的代碼諸如i f和循環語句及循環退出結構。如果不指明采取動作,awk將打印出所有瀏覽出來的記錄。

 

awk執行時,其瀏覽域標記為$1,$2...$n。這種方法稱為域標識。使用這些域標識將更容易對域進行進一步處理。

 

使用$1 , $3表示參照第1和第3域,注意這里用逗號做域分隔。如果希望打印一個有5個域

的記錄的所有域,不必指明$1 , $2 , $3 , $4 , $5,可使用$0,意即所有域。

為打印一個域或所有域,使用print命令。這是一個awk動作

 

awk的運行過程:

①  如果BEGIN 區塊存在,awk執行它指定的actions。

②   awk從輸入文件中讀取一行,稱為一條輸入記錄。(如果輸入文件省略,將從標准輸入讀取)

③   awk將讀入的記錄分割成字段,將第1個字段放入變量$1中,第2個字段放入$2,以此類推。$0表示整條記錄。

④   把當前輸入記錄依次與每一個awk_cmd中awk_pattern比較,看是否匹配,如果相匹配,就執行對應的actions。如果不匹配,就跳過對應的actions,直到比較完所有的awk_cmd。

⑤   當一條輸入記錄比較了所有的awk_cmd后,awk讀取輸入的下一行,繼續重復步驟③和④,這個過程一直持續,直到awk讀取到文件尾。

⑥   當awk讀完所有的輸入行后,如果存在END,就執行相應的actions。

實例:

例1:顯示/etc/passwd文件中的用戶名和登錄shell 

顯示/etc/passwd的賬戶和賬戶對應的shell,而賬戶與shell之間以tab鍵分割

顯示/etc/passwd文件中的用戶名和登錄shell, 而賬戶與shell之間以逗號分割

 

 

注:

1.awk 后面接兩個單引號並加上大括號 {} 來設定想要對數據進行的處理動作

2.awk工作流程是這樣的:先執行BEGING,然后讀取文件,讀入有\n換行符分割的一條記錄,然后將記錄按指定的域分隔符划分域,填充域,$0則表示所有域,$1表示第一個域,$n


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM