正則表達式又稱正規表達式、常規表達式。在代碼中常簡寫爲 regex、regexp 或 RE。正則表達式是使用單個字符串來描述、匹配一系列符合某個句法規則的字符串,簡單來講, 是一種匹配字符串的方法,經過一些特殊符號,實現快速查找、刪除、替換某個特定字符串。
正則表達式是由普通字符與元字符組成的文字模式。模式用於描述在搜索文本時要匹配的一個或多個字符串。正則表達式做爲一個模板,將某個字符模式與所搜索的字符串進行匹配。其中普通字符包括大小寫字母、數字、標點符號及一些其餘符號,元字符則是指那些在正則表達式中具備特殊意義的專用字符,能夠用來規定其前導字符(即位於元字符前面的字符)在目標對象中的出現模式。
正則表達式通常用於腳本編程與文本編輯器中。不少文本處理器與程序設計語言均支持正則表達式,如前面提到的 Perl、Linux 系統中常見的文本處理器(grep、egrep、sed、awk)。正則表達式具有很強大的文本匹配功能,可以在文本海洋中快速高效地處理文本。html
正則表達式的字符串表達方法根據不一樣的嚴謹程度與功能分爲基本正則表達式與擴展正則表達式。基礎正則表達式是經常使用的正則表達式的最基礎的部分。在 Linux 系統中常見的文件處理工具中 grep 與 sed 支持基礎正則表達式,而 egrep 與 awk 支持擴展正則表達式。掌握基礎正則表達式的使用方法,首先必須瞭解基本正則表達式所包含的元字符的含義,下面咱們複製一份http服務的配置文件來進行演示。正則表達式
[root@localhost ~]# cp /etc/httpd/conf/httpd.conf /opt/httpd.txt [root@localhost ~]# cat /opt/httpd.txt # # This is the main Apache HTTP server configuration file. It contains the # configuration directives that give the server its instructions. # See <URL:http://httpd.apache.org/docs/2.4/> for detailed information. # In particular, see # <URL:http://httpd.apache.org/docs/2.4/mod/directives.html> # for a discussion of each configuration directive. .................................. //省略部份內容
查找特定字符很是簡單,如執行如下命令便可從 httpd.txt 文件中查找出特定字符「do」 所在位置。其中「-n」表示顯示行號、「-i」表示不區分大小寫。命令執行後,符合匹配標準的字符,字體顏色會變爲紅色。shell
若反向選擇,如查找不包含「do」字符的行,則須要經過 grep 命令的「-vn」選項實現。express
[root@localhost opt]# grep -vn 'do' httpd.txt 1:# 2:# This is the main Apache HTTP server configuration file. It contains the 3:# configuration directives that give the server its instructions. 5:# In particular, see 7:# for a discussion of each configuration directive. 8:# 。........................... //省略部份內容
想要查找「shirt」與「short」這兩個字符串時,能夠發現這兩個字符串均包含「sh」 與「rt」。此時執行如下命令便可同時查找到「shirt」與「short」這兩個字符串。「[]」中不管有幾個字符,都僅表明一個字符,也就是說「[io]」表示匹配「i」或者「o」。apache
[root@localhost opt]# tail -3 httpd.txt short shirt shart [root@localhost opt]# grep -n 'sh[io]rt' httpd.txt 354:short 355:shirt [root@localhost opt]#
若要查找包含重複單個字符「oo」時,只須要執行如下命令便可。編程
[root@localhost opt]# head -5 httpd.txt wood woood wooood woooood # [root@localhost opt]# grep -n 'oo' httpd.txt 1:wood 2:woood 3:wooood 4:woooood
若查找「oo」前面不是「w」的字符串,只須要經過集合字符的反向選擇「[^]」來實現該目的,如執行「grep –n'[^w]oo'httpd.txt」命令表示在 httpd.txt 文本中查找「oo」 前面不是「w」的字符串。執行結果看到「woood」仍是查找到了,由於「oo」前面是「o」也不是「w」,符合條件,其它同理。vim
若不但願「oo」前面存在小寫字母,可使用「grep –n'[^a-z]oo'httpd.txt」命令實現,其中「a-z」表示小寫字母,大寫字母則經過「A-Z」表示。bash
查找包含數字的行能夠經過「grep –n'[0-9]' httpd.txt」命令來實現。運維
基礎正則表達式包含兩個定位元字符:「^」(行首)與「$」(行尾)。在上面的示例中,查詢「the」字符串時出現了不少包含「the」的行,若是想要查詢以「the」字符串爲行首的行,則能夠經過「^」元字符來實現。ssh
查詢以小寫字母開頭的行能夠經過「^[a-z]」規則來過濾,查詢大寫字母開頭的行則使用「^[A-Z]」規則,若查詢不以字母開頭的行則使用「^[^a-zA-Z]」規則。
[root@localhost opt]# grep -n '^[a-z]' httpd.txt 1:wood 2:woood 3:wooood 4:woooood 358:short 359:shirt 360:shart [root@localhost opt]# grep -n '^[A-Z]' httpd.txt 35:ServerRoot "/etc/httpd" 46:Listen 80 60:Include conf.modules.d/*.conf 70:User apache 71:Group apache
「^」符號在元字符集合「[]」符號內外的做用是不同的,在「[]」符號內表示反向選擇,在「[]」符號外則表明定位行首。反之,若想查找以某一特定字符結尾的行則可使用「$」定位符。例如,執行如下命令便可實現查詢以小數點(.)結尾的行。由於小數點(.) 在正則表達式中也是一個元字符(後面會講到),因此在這裏須要用轉義字符「\」將具備特 殊意義的字符轉化成普通字符。
當查詢空白行時,執行「grep –n'^$'httpd.txt」命令便可。
前面提到,在正則表達式中小數點(.)也是一個元字符,表明任意一個字符。例如, 執行如下命令就能夠查找「w??d」的字符串,即共有四個字符,以 w 開頭 d 結尾。
在上述結果中,「wood」字符串「w..d」匹配規則。若想要查詢 oo、ooo、ooooo 等資料,則須要使用星號(*)元字符。但須要注意的是,「*」表明的是重複零個或多個前面的單字符。「o*」表示擁有零個(即爲空字符)或大於等於一個「o」的字符,由於容許空字符,因此執行「grep –n‘o*’httpd.txt」命令會將文本中全部的內容都輸出打印。若是是「oo*」, 則第一個 o 必須存在,第二個 o 則是零個或多個 o,因此凡是包含 o、oo、ooo、ooo,等的資料都符合標準。同理,若查詢包含至少兩個 o 以上的字符串,則執行「grep –n'ooo*' httpd.txt」命令便可。
查詢以 w 開頭 d 結尾,中間包含至少一個 o 的字符串,執行如下命令便可實現。
查詢以 w 開頭 d 結尾,中間的字符無關緊要的字符串。
查詢任意數字所在行。
在上面的示例中,咱們使用「.」與「*」來設定零個到無限多個重複的字符,若是想要限制一個範圍內的重複的字符串該如何實現呢?例如,查找三到五個 o 的連續字符,這個時候就須要使用基礎正則表達式中的限定範圍的字符「{}」。由於「{}」在 Shell 中具備特殊 意義,因此在使用「{}」字符時,須要利用轉義字符「\」,將「{}」字符轉換成普通字符。 「{}」字符的使用方法以下所示。
經過上面幾個簡單的示例,咱們能夠了解到常見的基礎正則表達式的元字符主要包括如下幾個:
元字符 | 做用 |
---|---|
^ | 匹配輸入字符串的開始位置。除非在方括號表達式中使用,表示不包含該字符集合。要匹配「^」字符自己,請使用「\^」 |
$ | 匹配輸入字符串的結尾位置。若是設置了 RegExp 對象的 Multiline 屬性,則「$」也匹配‘\n’或‘\r’。要匹配「$」字符自己,請使用「\$」 |
. | 匹配除「\r\n」以外的任何單個字符 |
\|將下一個字符標記爲特殊字符、原義字符、向後引用、八進制轉義符。例如,‘n’匹配字符「n」。 ‘\n’匹配換行符。序列‘\’匹配「\」,而‘(’則匹配「(」 | |
* | 匹配前面的子表達式零次或屢次。要匹配「*」字符,請使用「*」 |
[] | 字符集合。匹配所包含的任意一個字符。例如,「[abc]」能夠匹配「plain」中的「a」 |
[^] | 賦值字符集合。匹配未包含的一個任意字符。例如,「[^abc]」能夠匹配「plain」中「plin」中的任何一個字母 |
[n1-n2] | 字符範圍。匹配指定範圍內的任意一個字符。例如,「[a-z]」能夠匹配「a」到「z」範圍內的任意一個小寫字母字符。注意:只有連字符(-)在字符組內部,而且出如今兩個字符之間時,才能表示字符的範圍;若是出如今字符組的開頭,則只能表示連字符自己 |
{n} | n 是一個非負整數,匹配肯定的 n 次。例如,「o{2}」不能匹配「Bob」中的「o」,可是能匹配「food」中的兩個 o |
{n,} | n 是一個非負整數,至少匹配 n 次。例如,「o{2,}」不能匹配「Bob」中的「o」,但能匹配「foooood」中的全部 o。「o{1,}」等價於「o+」。「o{0,}」則等價於「o*」 |
{n,m} | m 和n 均爲非負整數,其中 n<=m,最少匹配 n 次且最多匹配 m 次 |
一般狀況下會使用基礎正則表達式就已經足夠了,但有時爲了簡化整個指令,須要使用範圍更廣的擴展正則表達式。例如,使用基礎正則表達式查詢除文件中空白行與行首爲「#」 以外的行(一般用於查看生效的配置文件),執行「grep –v‘^$’test.txt | grep –v ‘^#’」便可實現。這裏須要使用管道命令來搜索兩次。若是使用擴展正則表達式,能夠簡化爲「egrep –v‘^$|^#’test.txt」,其中,單引號內的管道符號表示或者(or)。
此外,grep 命令僅支持基礎正則表達式,若是使用擴展正則表達式,須要使用 egrep 或 awk 命令。awk 命令在後面的小節進行講解,這裏咱們直接使用 egrep 命令。egrep 命令與 grep 命令的用法基本類似。egrep 命令是一個搜索文件得到模式,使用該命令能夠搜索文件中的任意字符串和符號,也能夠搜索一個或多個文件的字符串,一個提示符能夠是單個字符、一個字符串、一個字或一個句子。與基礎正則表達式類型相同,擴展正則表達式也包含多個元字符,常見的擴展正則表達式的元字符主要包括如下幾個:
下面分別演示每一個例子
示例1:執行「egrep -n 'wo+d' httpd.txt」命令,便可查詢"wood" "woood" "woooooood"等字符串
示例2:執行「egrep -n 'bes?t' httpd.txt」命令,便可查詢「bet」「best」這兩個字符串
示例3:執行「egrep -n 'of|is|on' httpd.txt」命令便可查詢"of"或者"if"或者"on"字符串
示例4:「egrep -n 't(a|e)st' test.txt」。「tast」與「test」由於這兩個單詞的「t」與「st」是重複的,因此將「a」與「e」列於「()」符號當中,並以「|」分隔,便可查詢"tast"或者"test"字符串
示例5:「egrep -n 'A(xyz)+C' test.txt」。該命令是查詢開頭的"A"結尾是"C",中間有一個以上的 "xyz"字符串的意思
在 Linux/UNIX 系統中包含不少種文本處理器或文本編輯器,其中包括咱們以前學習過的VIM 編輯器與 grep 等。而 grep,sed,awk 更是 shell 編程中常常用到的文本處理工具,被稱之爲 Shell 編程三劍客。
sed(Stream EDitor)是一個強大而簡單的文本解析轉換工具,能夠讀取文本,並根據指定的條件對文本內容進行編輯(刪除、替換、添加、移動等),最後輸出全部行或者僅輸出處理的某些行。sed 也能夠在無交互的狀況下實現至關複雜的文本處理操做,被普遍應用於 Shell 腳本中,用以完成各類自動化處理任務。
sed 的工做流程主要包括讀取、執行和顯示三個過程。
讀取:sed 從輸入流(文件、管道、標準輸入)中讀取一行內容並存儲到臨時的緩衝區中(又稱模式空間,pattern space)。
執行:默認狀況下,全部的 sed 命令都在模式空間中順序地執行,除非指定了行的地址,不然 sed 命令將會在全部的行上依次執行。
顯示:發送修改後的內容到輸出流。再發送數據後,模式空間將會被清空。在全部的文件內容都被處理完成以前,上述過程將重複執行,直至全部內容被處理完。
注意:默認狀況下,全部的 sed 命令都是在模式空間內執行的,所以輸入的文件並不會發生任何變化,除非是用重定向存儲輸出。
一般狀況下調用 sed 命令有兩種格式,以下所示。其中,「參數」是指操做的目標文件,當存在多個操做對象時用,文件之間用逗號「,」分隔;而 scriptfile 表示腳本文件,須要用「-f」選項指定,當腳本文件出如今目標文件以前時,表示經過指定的腳本文件來處理輸入的目標文件。
sed[選項] '操做' 參數 sed [選項] -f scriptfile 參數
常見的 sed 命令選項主要包含如下幾種:
-e 或--expression=:表示用指定命令或者腳原本處理輸入的文本文件 -f 或--file=:表示用指定的腳本文件來處理輸入的文本文件 -h 或--help:顯示幫助 -n、--quiet 或 silent:表示僅顯示處理後的結果 -i:直接編輯文本文件
「操做」用於指定對文件操做的動做行爲,也就是 sed 的命令。一般狀況下是採用的「[n1[,n2]]」操做參數的格式。n一、n2 是可選的,不必定會存在,表明選擇進行操做的行數,如操做須要在 5~20 行之間進行,則表示爲「5,20 動做行爲」。常見的操做包括如下幾種。
a:增長,在當前行下面增長一行指定內容。 c:替換,將選定行替換爲指定內容。 d:刪除,刪除選定的行。 i:插入,在選定行上面插入一行指定內容。 p:打印,若是同時指定行,表示打印指定行;若是不指定行,則表示打印全部內容; 若是有非打印字符,則以ASCII 碼輸出。其一般與「-n」選項一塊兒使用。 s:替換,替換指定字符。 y:字符轉換。
咱們先本身新建一個test.txt文本文件做爲實驗對象:
[root@localhost opt]# vim test.txt [root@localhost opt]# cat test.txt 1 2 3 4 5 6 7 8 9 0 [root@localhost opt]#
[root@localhost opt]# sed -n 'p' test.txt //輸出全部內容,等同於 cat test.txt 1 2 3 4 5 6 7 8 9 0 [root@localhost opt]# [root@localhost opt]# sed -n '2,5p' test.txt //輸出 2~5 行 2 3 4 5 [root@localhost opt]# [root@localhost opt]# sed -n 'p;n' test.txt //輸出全部奇數行,n 表示讀入下一行資料 1 3 5 7 9 [root@localhost opt]# sed -n 'n;p' test.txt //輸出全部偶數行,n 表示讀入下一行資料 2 4 6 8 0 [root@localhost opt]# [root@localhost opt]# sed -n '2,${p;n}' test.txt //輸出第 2 行至文件尾之間的奇數行 2 4 6 8 0 [root@localhost opt]#
在執行「sed –n‘2,${n;p}’test.txt」命令時,讀取的第 1 行是文件的第 2 行,讀取的第 2 行是文件的第 3 行,依此類推,因此輸出的奇數行是文件的第 2 行、4 行直至文件結尾,其中包括空行。
以上是 sed 命令的基本用法,sed 命令結合正則表達式時,格式略有不一樣,正則表達式以「/」包圍。例如,如下操做是 sed 命令與正則表達式結合使用的示例。
[root@localhost opt]# vim test.txt //先對實驗文件進行修改 [root@localhost opt]# cat test.txt 1 2 3 4 5 6 7 the this 8 this the 9 0 [root@localhost opt]# [root@localhost opt]# sed -n '/the/p' test.txt //輸出包含the 的行 the this this the [root@localhost opt]# [root@localhost opt]# sed -n '2,/the/p' test.txt //輸出從第 2 行至第一個包含 the 的行 2 3 4 5 6 7 the this [root@localhost opt]# [root@localhost opt]# sed -n '/the/=' test.txt //輸出包含the 的行所在的行號,等號(=)用來輸出行號 8 10 [root@localhost opt]# [root@localhost opt]# sed -n '/^the/p' test.txt //輸出以the 開頭的行 the this [root@localhost opt]# [root@localhost opt]# sed -n '/^the/p' test.txt //輸出以the開頭的行 the this [root@localhost opt]# [root@localhost opt]# sed -n '/[0-9]$/p' test.txt //輸出以數字結尾的行 1 2 3 4 5 6 7 8 9 0 [root@localhost opt]# [root@localhost opt]# vim test.txt //在文本末行添加一個"then" [root@localhost opt]# cat test.txt 1 2 3 4 5 6 7 the this 8 this the 9 0 then [root@localhost opt]# sed -n '/the/p' test.txt //輸出包含the的行,注意這種輸出不會識別單詞 the this this the then [root@localhost opt]# sed -n '/\<the\>/p' test.txt //輸出包含單詞the的行,\<、\>表明單詞邊界 the this this the [root@localhost opt]#
刪除符合條件的文本(d)
由於後面的示例還須要使用測試文件 test.txt,因此在執行刪除操做以前須要先將測試文件備份。如下示例分別演示了 sed 命令的幾種經常使用刪除用法。
下面命令中 nl 命令用於計算文件的行數,結合該命令能夠更加直觀地查看到命令執行的結果。
[root@localhost opt]# nl test.txt | sed '3d' //刪除第 3 行 1 1 2 2 4 4 5 5 6 6 7 7 8 the this 9 8 10 this the 11 9 12 0 13 then [root@localhost opt]# [root@localhost opt]# nl test.txt | sed '3d' //刪除第 3~5 行 1 1 2 2 6 6 7 7 8 the this 9 8 10 this the 11 9 12 0 13 then [root@localhost opt]# [root@localhost opt]# nl test.txt | sed '/the/d' //刪除包含cross 的行 1 1 2 2 3 3 4 4 5 5 6 6 7 7 9 8 11 9 12 0 [root@localhost opt]# nl test.txt | sed '/the/!d' //刪除不包含cross 的行,用!符號表示取反操做,如'/the/!d' 8 the this 10 this the 13 then [root@localhost opt]# [root@localhost opt]# sed '/^[a-z]/d' test.txt //刪除以小寫字母開頭的行 1 2 3 4 5 6 7 8 9 0 THE this [root@localhost opt]# [root@localhost opt]# sed '/this$/d' test.txt //刪除以this結尾的行 1 2 3 4 5 6 7 8 this the 9 0 then [root@localhost opt]# [root@localhost ~]# sed '/^$/d' test.txt //刪除全部空行,與前面的差很少,不演示了
注意: 如果刪除重複的空行,即連續的空行只保留一個, 執行「 sed –e ‘/^$/{n;/^$/d}’test.txt」命令便可實現。其效果與「cat -s test.txt」相同,n 表示讀下一行數據。
替換符合條件的文本
在使用 sed 命令進行替換操做時須要用到 s(字符串替換)、c(整行/整塊替換)、y(字符轉換)命令選項,常見的用法以下所示。
sed 's/the/THE/' test.txt //將每行中的第一個the 替換爲 THE sed 's/l/L/2' test.txt //將每行中的第 3 個l 替換爲L sed 's/the/THE/g' test.txt //將文件中的全部the 替換爲THE sed 's/o//g' test.txt //將文件中的全部o 刪除(替換爲空串) sed 's/^/#/' test.txt //在每行行首插入#號 sed '/the/s/^/#/' test.txt //在包含the 的每行行首插入#號 sed 's/$/EOF/' test.txt //在每行行尾插入字符串EOF sed '3,5s/the/THE/g' test.txt //將第 3~5 行中的全部the 替換爲 THE sed '/the/s/o/O/g' test.txt //將包含the 的全部行中的o 都替換爲 O
遷移符合條件的文本
其中,H,複製到剪貼板;g、G,將剪貼板中的數據覆蓋/追加至指定行;w,保存爲文件;r,讀取指定文件;a,追加指定內容。
sed '/the/{H;d};$G' test.txt //將包含the 的行遷移至文件末尾,{;}用於多個操做 sed '1,5{H;d};17G' test.txt //將第 1~5 行內容轉移至第 17 行後 sed '/the/w out.file' test.txt //將包含the 的行另存爲文件out.file sed '/the/r /etc/hostname' test.txt //將文件/etc/hostname 的內容添加到包含the 的每行之後 sed '3aNew' test.txt //在第 3 行後插入一個新行,內容爲 New sed '/the/aNew' test.txt //在包含the 的每行後插入一個新行,內容爲 New sed '3aNew1\nNew2' test.txt //在第 3 行後插入多行內容,中間的\n 表示換行
使用腳本編輯文件
使用 sed 腳本,將多個編輯指令存放到文件中(每行一條編輯指令),經過「-f」選項來調用。例如:
sed '1,5{H;d};17G' test.txt //將第 1~5 行內容轉移至第 10 行後
以上操做能夠改用腳本文件方式:
[root@localhost opt]# vim opt.list [root@localhost opt]# cat opt.list 1,5H 1,5d 10G [root@localhost opt]# sed -f opt.list test.txt 6 7 the this 8 this the 1 2 3 4 5 9 0 then THE this [root@localhost opt]#
sed 直接操做文件示例
編寫一個腳本,用來調整 vsftpd 服務配置:禁止匿名用戶,但容許本地用戶(也容許寫入)。
[root@localhost ~]# vim local_only_ftp.sh #!/bin/bash # 指定樣本文件路徑、配置文件路徑 SAMPLE="/usr/share/doc/vsftpd-3.0.2/EXAMPLE/INTERNET_SITE/vsftpd.conf " CONFIG="/etc/vsftpd/vsftpd.conf" # 備份原來的配置文件,檢測文件名爲/etc/vsftpd/vsftpd.conf.bak 備份文件是否存在,若不存在則使用 cp 命令進行文件備份 [ ! -e "$CONFIG.bak" ] && cp $CONFIG $CONFIG.bak # 基於樣本配置進行調整,覆蓋現有文件 sed -e '/^anonymous_enable/s/YES/NO/g' $SAMPLE > $CONFIG sed -i -e '/^local_enable/s/NO/YES/g' -e '/^write_enable/s/NO/YES/g' $CONFIG grep "listen" $CONFIG || sed -i '$alisten=YES' $CONFIG # 啓動vsftpd 服務,並設爲開機後自動運行 systemctl restart vsftpd systemctl enable vsftpd [root@localhost ~]# chmod +x local_only_ftp.sh
在 Linux/UNIX 系統中,awk 是一個功能強大的編輯工具,逐行讀取輸入文本,並根據指定的匹配模式進行查找,對符合條件的內容進行格式化輸出或者過濾處理,能夠在無交互的狀況下實現至關複雜的文本操做,被普遍應用於 Shell 腳本,完成各類自動化配置任務。
一般狀況下 awk 所使用的命令格式以下所示,其中,單引號加上大括號「{}」用於設置對數據進行的處理動做。awk 能夠直接處理目標文件,也能夠經過「-f」讀取腳本對目標文件進行處理。
awk 選項 '模式或條件 {編輯指令}' 文件 1 文件 2 „ //過濾並輸出文件符條件的內容 awk -f 腳本文件 文件 1 文件 2 „ //從腳本中調用編輯指令,過濾並輸出內容
前面提到 sed 命令經常使用於一整行的處理,而 awk 比較傾向於將一行分紅多個「字段」而後再進行處理,且默認狀況下字段的分隔符爲空格或者 tab 鍵。awk 執行結果能夠經過 print 的功能將字段數據打印顯示。在使用 awk 命令的過程當中,可使用邏輯操做符「&&」,表示「與」, 「||」表示「或」,「!」表示「非」;還能夠進行簡單的數學運算,如+、-、*、/、%、^分別 表示加、減、乘、除、取餘和乘方。
在 Linux 系統中/etc/passwd 是一個很是典型的格式化文件,各字段間使用「:」做爲分隔符隔開,Linux 系統中的大部分日誌文件也是格式化文件,從這些文件中提取相關信息是運維的平常工做內容之一。若須要查出/etc/passwd 的用戶名、用戶 ID、組 ID 等列, 執行如下 awk 命令便可。
[root@localhost ~]# awk -F ':' '{print $1,$3,$4}' /etc/passwd root 0 0 bin 1 1 daemon 2 2 „„//省略部份內容
awk 從輸入文件或者標準輸入中讀入信息,與 sed 同樣,信息的讀入也是逐行讀取的。不一樣的是 awk 將文本文件中的一行視爲一個記錄,而將一行中的某一部分(列)做爲記錄中的一個字段(域)。爲了操做這些不一樣的字段,awk 借用 shell 中相似於位置變量的方法, 用$一、$二、$3順序地表示行(記錄)中的不一樣字段。另外 awk 用$0 表示整個行(記錄)。不一樣的字段之間是經過指定的字符分隔。awk 默認的分隔符是空格。awk 容許在命令行中用「-F 分隔符」的形式來指定分隔符。
awk 包含幾個特殊的內建變量(可直接用)以下所示:
FS:指定每行文本的字段分隔符,默認爲空格或製表位; NF:當前處理的行的字段個數; NR:當前處理的行的行號(序數); $0:當前處理的行的整行內容; $n:當前處理行的第 n 個字段(第 n 列); FILENAME:被處理的文件名; RS:數據記錄分隔,默認爲\n,即每行爲一條記錄。
按行輸出文本
[root@localhost opt]# awk '{print}' test.txt //輸出全部內容,等同於 cat test.txt 1 2 3 4 5 6 7 the this 8 this the 9 0 then THE this [root@localhost opt]# awk '{print $0}' test.txt //輸出全部內容,等同於 cat test.txt 1 2 3 4 5 6 7 the this 8 this the 9 0 then THE this [root@localhost opt]# [root@localhost opt]# awk 'NR==1,NR==3{print}' test.txt //輸出第 1~3 行內容 1 2 3 [root@localhost opt]# awk '(NR>=1)&&(NR<=3){print}' test.txt //輸出第 1~3 行內容 1 2 3 [root@localhost opt]# [root@localhost opt]# awk 'NR==1||NR==3{print}' test.txt //輸出第 1 行、第 3 行內容 1 3 [root@localhost opt]# [root@localhost opt]# nl test.txt|awk '(NR%2)==1{print}' //輸出全部奇數行的內容,nl顯示行號 1 1 3 3 5 5 7 7 9 8 11 9 13 then [root@localhost opt]# nl test.txt|awk '(NR%2)==0{print}' //輸出全部偶數行的內容,nl顯示行號 2 2 4 4 6 6 8 the this 10 this the 12 0 14 THE this [root@localhost opt]# [root@localhost opt]# awk '/^root/{print}' /etc/passwd //輸出以root 開頭的行 root:x:0:0:root:/root:/bin/bash [root@localhost opt]# [root@localhost opt]# awk '/bash$/{print}' /etc/passwd //輸出以 bash 結尾的行 root:x:0:0:root:/root:/bin/bash jiang:x:1000:1000:jiang:/home/jiang:/bin/bash [root@localhost opt]# [root@localhost opt]# awk 'BEGIN{x=0};/\/bin\/bash$/{x++};END{print x}' /etc/passwd //統計以/bin/bash 結尾的行數,等同於 grep -c "/bin/bash$" /etc/passwd 2 [root@localhost opt]# [root@localhost opt]# awk 'BEGIN{RS=""};END{print NR}' /etc/httpd/conf/httpd.conf //統計以空行分隔的文本段落數 38 [root@localhost opt]#
按字段輸出文本
awk '{print $3}' /etc/passwd //輸出每行中(以空格或製表位分隔)的第 3 個字段 awk '{print $1,$3}' /etc/passwd //輸出每行中的第 一、3 個字段 awk -F ":" '$2==""{print}' /etc/shadow //輸出密碼爲空的用戶的shadow 記錄 awk 'BEGIN {FS=":"}; $2==""{print}' /etc/shadow//輸出密碼爲空的用戶的shadow 記錄 awk -F ":" '$7~"/bash"{print $1}' /etc/passwd//輸出以冒號分隔且第 7 個字段中包含/bash 的行的第 1 個字段 awk '($1~"nfs")&&(NF==8){print $1,$2}' /etc/services//輸出包含 8 個字段且第 1 個字段中包含 nfs 的行的第 一、2 個字段 awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd//輸出第 7 個字段既不爲/bin/bash 也不爲/sbin/nologin 的全部行
經過管道、雙引號調用 Shell 命令
awk -F: '/bash$/{print | "wc -l"}' /etc/passwd //調用wc -l 命令統計使用bash 的用戶個數,等同於 grep -c "bash$" /etc/passwd awk 'BEGIN {while ("w" | getline) n++ ; {print n-2}}' //調用w 命令,並用來統計在線用戶數 awk 'BEGIN { "hostname" | getline ; print $0}' //調用hostname,並輸出當前的主機名
sort 是一個以行爲單位對文件內容進行排序的工具,也能夠根據不一樣的數據類型來排序。例如數據和字符的排序就不同。sort 命令的語法爲「sort [選項] 參數」,其中經常使用的選項包括如下幾種。
-f:忽略大小寫; -b:忽略每行前面的空格; -M:按照月份進行排序; -n:按照數字進行排序; -r:反向排序; -u:等同於 uniq,表示相同的數據僅顯示一行; -t:指定分隔符,默認使用[Tab]鍵分隔; -o <輸出文件>:將排序後的結果轉存至指定文件; -k:指定排序區域。
示例 1:將/etc/passwd 文件中的帳號進行排序。
[root@localhost ~]# sort /etc/passwd abrt:x:173:173::/etc/abrt:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin haldaemon:x:68:68:HAL daemon:/:/sbin/nologin halt:x:7:0:halt:/sbin:/sbin/halt lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin root:x:0:0:root:/root:/bin/bash rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync tcpdump:x:72:72::/:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
示例 2:將/etc/passwd 文件中第三列進行反向排序。
[root@localhost ~]# sort -t ':' -rk 3 /etc/passwd nobody:x:99:99:Nobody:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin halt:x:7:0:halt:/sbin:/sbin/halt vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin haldaemon:x:68:68:HAL daemon:/:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown sync:x:5:0:sync:/sbin:/bin/sync rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin root:x:0:0:root:/root:/bin/bash
示例3:將/etc/passwd 文件中第三列進行排序,並將輸出內容保存至user.txt 文件中。
[root@localhost ~]# sort -t ':' -k 3 /etc/passwd -o user.txt [root@localhost ~]# cat user.txt root:x:0:0:root:/root:/bin/bash uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin a dm:x:3:4:adm:/var/adm:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin haldaemon:x:68:68:HAL daemon:/:/sbin/nologin vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin halt:x:7:0:halt:/sbin:/sbin/halt tcpdump:x:72:72::/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin
Uniq 工具在 Linux 系統中一般與 sort 命令結合使用,用於報告或者忽略文件中的重複行。具體的命令語法格式爲:uniq [選項] 參數。其中經常使用選項包括如下幾種。
-c:進行計數; -d:僅顯示重複行; -u:僅顯示出現一次的行;
示例 1:刪除 testfile 文件中的重複行。
[root@localhost ~]# cat testfile Linux 10 Linux 20 Linux 30 Linux 30 Linux 30 CentOS 6.5 CentOS 6.5 CentOS 6.5 CentOS 7.3 CentOS 7.3 CentOS 7.3 [root@localhost ~]# uniq testfile Linux 10 Linux 20 Linux 30 CentOS 6.5 CentOS 7.3
示例 2:刪除 testfile 文件中的重複行,並在行首顯示該行重複出現的次數。
[root@localhost ~]# uniq -c testfile 1 Linux 10 1 Linux 20 3 Linux 30 3 CentOS 6.5 3 CentOS 7.3
示例 3:查找 testfile 文件中的重複行。
[root@localhost ~]# uniq -d testfile Linux 30 CentOS 6.5 CentOS 7.3