正則表達式和sed命令的用法

1、            正則表達式:linux

 

正則表達式(或稱Regular Expression,簡稱RE)就是由普通字符(例如字符 a z)以及特殊字符(稱爲元字符)組成的文字模式。正則表達式

 

該模式描述在查找文字主體時待匹配的一個或多個字符串。shell

 

正則表達式做爲一個模板,將某個字符模式與所搜索的字符串進行匹配。簡單的說,正則表示式就是處理字符串的方法,它是以行爲單位來進行字符串的處理行爲,正則表示式經過一些特殊符號的輔助,可讓使用者輕易的達到搜尋/刪除/取代某特定字符串的處理程序。vimgrepfindawksed等命令都支持正則表達式。express

經常使用正則表達式:vim

1.表明任意單個字符,如:/l..e/與包含一個l,後跟兩個字符,而後跟一個e的行相匹配編輯器

         grep l..e testide

         awk /l..e/ testwordpress

 

         cat  test(查看文件)函數

                   leeet工具

                   laat

                   lae

2^表明行的開始。 ^love 如:與全部love開頭的行匹配

        

3$表明行的結束。love$ 如:與全部love結尾的行匹配

那麼‘^$’ 就表示空行

 

4[]匹配括號中的字符之一

[abc]     匹配單個字符abc

[123]     匹配單個字符123

[a-z]     匹配小寫字母a-z之一

[a-zA-Z]    匹配任意英文字母之一

[0-9a-zA-Z]匹配任意英文字母或數字之一

注意:上面標紅色的單個和之一,無論[]裏面多複雜,它的結果都是一個字符!

         grep l[ae]e test

         awk /l[ae]e/ test

 

能夠用^標記作[]內的前綴,表示[]內的字符以外的字符。好比搜索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或多個連續的.  \.表示普通字符句點

 

sed s/^ *[0-9]*// test1

history > test1(先生成test1文件)

10|表示  如:a|b|c 匹配abc。如:grep|sed匹配grepsed

    如:egrep grep|sed test

11(),將部份內容合成一個單位組,好比要搜索 glad good能夠以下 'g(la|oo)d'

         如:egrep ‘g(la|oo)d’ test

綜合舉例1:

1 Christian Scott lives here and will put ona 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][a-z]$

搜索以0個或多個空格開頭,跟一個大寫字母,兩個小寫字母和一個換車符。將找到第4行的TOM(整行匹配)和第5行。注意,*前面有一個空格

 

^[A-Za-z]*[^,][A-Za-z]*$

將查找以0個或多個大寫或小寫字母開頭,不跟逗號,而後跟0個或多個大寫或小寫字母,而後跟一個換車符。將找到第4和5行。

 

2、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" 選項

spacer.gif

取得eth0網卡IP地址:

spacer.gif

 

2刪除行:d命令

從某文件中刪除包含"how" 的全部行

spacer.gif

 

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

spacer.gif

 

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

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

 

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

a的後面能夠接字符串,而這些字符串會在新的一行出現

/etc/passwd的第二行後增長「XXXXX」字樣的新行

spacer.gif

 

/etc/passwd的第二行前增長「XXXXX」字樣的新行

spacer.gif

 

若是要同時新增多行,則每行之間要用反斜槓\來進行新行的添加

spacer.gif

4、取代行:c命令

c的後面能夠接字符串,這些字符串能夠取代n1,n2之間的行

spacer.gif

 

5、打印:p命令

sed'/north/p' datafile 默認輸出全部行,找到north的行重複打印

 

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

 

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

 

    sed -n "1p;3p;5p;7p;10p;15p"/etc/passwd顯示/etc/passwd的1,3,5,7,10,15行

 

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

    sed -i ‘23s/test/tset/g’ test.txt用sed修改test.txt的23行test爲tset;

sed  -i ‘1,3d’ /tmp/*.tmp  刪除每一個臨時文件的最初三行。

3、grep命令的用法

grep global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來.

 

參數:

1. -ANUM--after-context=NUM   除了列出符合行以外,而且列出後NUM行。

:   $ grep –A1 panda file  (file中搜尋有panda樣式的行,並顯示該行的後1)

 

2. -BNUM--before-context=NUM  -A NUM 相對,但這此參數是顯示除符合行以外並顯示在它以前的NUM行。如:    (file中搜尋有panda樣式的行,並顯示該行的前1)

$ grep -B 1 panda file

 

3 -C[NUM], -NUM, --context[=NUM]  列出符合行以外並列出上下各NUM行。

 

:   (列出file中除包含panda樣式的行外並列出其上下2)

$ grep –C 2 panda file

 

4 -c, --count  不顯示符合樣式行,只顯示符合的總行數。若再加上-v,--invert-match,參數顯示不符合的總行數

5-i--ignore-case 忽略大小寫差異

 

6-n--line-number 在匹配的行前面打印行號

 

7-v--revert-match  反檢索,只顯示不匹配的行

 

8、精確匹配:

例如在抽取字符串「 48」,返回結果包含諸如484483等包含「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
顯示在aabbcc文件中匹配test的行。

 

$ grep  '[a-z]\{5,\}'  aa
顯示全部包含每一個字符串至少有5個連續小寫字符的字符串的行。

 

$grep  ‘t[a|e]st’ filename

顯示包含testtast的全部行。

 

$grep  '\.$' filename

顯示以.爲結尾的全部行。

 

4、awk命令:

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

 

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

 

1.命令格式

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

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

:linux系統中用環境變量IFS存儲分隔符,但根據實際應用也能夠改變IFS的值.

例如:

spacer.gif

腳本執行結果以下:

spacer.gif

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

 

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

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

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

commands

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

模式包括兩個特殊字段 BEGINEND。使用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  [-F field-separator]  'commands' input-files

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

spacer.gif

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

spacer.gif

若是隻是顯示/etc/passwd文件中的用戶名和登陸shell, 而帳戶與shell之間以逗號分割

spacer.gif

注:awk的老是輸出到標準輸出,若是想讓awk輸出到文件,可使用重定向。

 

例2:顯示/etc/passwd文件中的UID大於500的全部用戶的用戶名和登陸shell

spacer.gif

例3:若是隻是顯示/etc/passwd文件中的UID大於500的用戶名和登陸shell,而帳戶與shell之間以逗號分割,並且在全部行添加列名name,shell,在最後一行添加"blue,/bin/nosh"。

spacer.gif

注:

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

2.awk工做流程是這樣的:先執行BEGING,而後讀取文件,讀入有\n換行符分割的一條記錄,而後將記錄按指定的域分隔符劃分域,填充域,$0則表示全部域,$1表示第一個域,$n表示第n個域,隨後開始執行模式所對應的動做。接着開始讀入第二條記錄······直到全部的記錄都讀完,最後執行END操做。

思考題:如何打印全部記錄(以/etc/passwd中的內容爲例)

spacer.gif

4:搜索/etc/passwdroot關鍵字的全部行

spacer.gif 

這種是pattern(模式)的使用示例,匹配了pattern(這裏是root)的行纔會執行action(沒有指定action,默認輸出每行的內容)

搜索支持正則表達式,例如找root開頭的:

spacer.gif

搜索/etc/passwdroot關鍵字的全部行,並顯示對應的shell

spacer.gif

這裏指定了action{print $7}

 

awk內置變量

awk有許多內置變量用來設置環境信息,下面給出了最經常使用的一些變量。

 FILENAME awk瀏覽的文件名

 FS   設置輸入域分隔符,等價於命令行-F選項

 NF   瀏覽記錄的域個數(每一行($0)擁有的字段總數)

 NR   已讀的記錄數(awk所處理的是第幾行數據)

   例5:1)查看/etc/passwd第25行第三列和第7列的內容。

  awk –F: ‘NR==25{print $1,$7}’ /etc/passwd

         2)顯示/etc/passwd的1,3,5,7,10,15行?

   awk'NR==1||NR==3||NR==5||NR==7||NR==10||NR=15{print $0}' /etc/passwd

 

除了awk的內置變量,awk還能夠自定義變量

 

6:統計/etc/passwd的帳戶人數

spacer.gif

count是自定義變量。以前的action{}裏都是隻有一個print,其實print只是一個語句,而action{}能夠有多個語句,以;號隔開。

這裏沒有初始化count,雖然默認是0,可是穩當的作法仍是初始化爲0:

spacer.gif

 

例7:統計某個文件夾下的文件佔用的字節數

spacer.gif

若是以M爲單位顯示:

spacer.gif

注意:以上統計沒有包括子目錄中的文件

若是想快速查看全部文件的長度及其總和,但要排除子目錄,如何實現:

spacer.gif

5、函數及腳本的綜合應用

 

1shell函數:shell容許將一組命令集或語句造成一個可用塊,這些塊稱爲shell函數。

 

函數由兩部分組成:函數標題、函數體。

 

標題是函數名。函數體是函數內的命令集合。

 

標題名應該惟一;若是不是,將會混淆結果,由於腳本在查看調用腳本前將首先搜索函數調用相應的shell

 

2定義函數的格式爲:

函數名(){

命令1

...

}

若是願意,可在函數名前加上關鍵字function,這取決於使用者。

function函數名()

{

  命令1

  ...

}

相關文章
相關標籤/搜索