1. 程式人生 > >2017-12-9Linux基礎知識(16)文本處理工具

2017-12-9Linux基礎知識(16)文本處理工具

linux 基礎

??我們簡述一下上一章的內容,主要講的是bash編程的基礎,介紹了其編程類型,以及介紹了編程語言的類型什麽是過程式編程和對象式編程,然後我們編寫了第一個腳本程序以及如何運行的方式有那些,之後又講了一些bash的配置文件,分別是profile類和bashrc類,前者為登錄式shell所提供,而後者是非登錄式shell所提供,之後對於shell的書寫格式我們也了解到了如何進行編輯以及格式的說明,那麽在這一章中,我們來講述Linux的文本處理工具。

一、Linux文本處理三劍客

??在Linux中的文本處理三劍客功能很強的主要就是grep、sed和awk;grep是一個文本過濾工具,以模式(pattern)的方式進行過濾,那麽sed是一個流式編輯器,所以它也是一個文本的編輯工具。而awk在Linux上實現為gawk,那麽它是一個文本報告生成器,它能夠格式化文本,以非常美觀的方式輸出的工具。

??那麽以上三個工具都會用到一個為正則表達式,那麽正則表達式就是由一類特殊字符及文本字符所編寫的模式,在這個表達式裏其中有些字符不表示其原來有的字面意義,而是用於表示控制或通配的功能,而正則表達式一共分為兩類,一種是基本正則表達式,另一種為擴展正則表達式,這兩者的區別就在於它們的元字符有所不同,而元字符的功能就是用於匹配和控制的功能,我們來總結一下:

???正則表達式:REGEXP
?????由一類特殊字符及文本字符所編寫的模式,其中有些字符不表示其原有的字面意義,而是用於表示控制或通配的功能;
????????分兩類:
????????????基本正則表達式:BRE
????????????擴展正則表達式:ERE
????????
????????元字符:用於匹配和控制功能;

二、grep工具

??在這一個章節中,我們在文本處理三劍客當中主要講的是grep工具,按行來進行搜索,逐行匹配,然後用戶指定其模式來進行匹配,如果某一行能被該模式所能匹配到,就在標準輸出中顯示匹配到的行。而模式就是由正則表達式的元字符及文本字符所編寫的過濾條件。不過這些正則表達式要想被識別的話,在該命令中就會正則表達式引擎來所識別正則表達式,無論是grep和sed以及awk,都是有不同的正則表達式引擎,所以元字符就是根據支持正則表達式的引擎而不同。

??好的,現在我們來介紹一下grep命令,其命令格式如下:

???grep?[OPTIONS]?PATTERN?[FILE...]
???grep?[OPTIONS]?[-e?PATTERN?|?-f?FILE]?[FILE...]
???作用:文本搜索工具,根據用戶指定的"模式(過濾條件)"對目標文本逐行進行匹配檢查;打印匹配到的行;
???模式:由正則表達式的元字符及文本字符所編寫出的過濾條件;

??例如,我們在/etc/passwd文件中找出匹配到user1相關用戶的行;

???#?grep?"user1"?/etc/passwd
???user1:x:1004:1004::/home/user1:/bin/bash

??這個是最基本的用法,那個引號可以不加,因為畢竟是字符串,之所以這樣是因為在CentOS 7都定義了其別名,換句話說,這不是原來的grep命令,而是別名的grep,需要註意的是,CentOS 6是沒有的,Debian也是沒有的。
??那麽grep支持那些常見的選項如下:

???--color=auto:對匹配到的文本著色後高亮顯示;
???-i,?--ignore-case:忽略字符的大小寫;
???-o,?--only-matching:僅匹配到字符串本身;
???-v,?--invert-match:顯示不能被模式匹配到的行;
???-E,?--extended-regexp:支持使用擴展的正則表達式元字符;
???-q,?--quiet,?--silent:靜默模式,即不輸出任何信息;

???-A?NUM,?--after-context=NUM:後#行;
???-B?NUM,?--before-context=NUM:前#行;
???-C?NUM,?-NUM,?--context=NUM:前後各#行;

??以上就是grep的選項,那麽在下面說一下基本正則表達式的元字符。
??基本正則表達式的元字符分為以下幾類進行匹配,分別是字符匹配、次數匹配、位置錨定和分組及引用,我們現在來一一列舉。

???基本正則表達式元字符:
??????字符匹配:
?????????.:匹配任意單個字符;
?????????[]:匹配制定範圍內的任意單個字符;
?????????[^]:匹配指定範圍外的任意單個字符;
????????????[:digit:],?[:lower:],?[:upper:],?[:alpha:],?[:alnum:],?[:punct:],?[:space:]
	
??????匹配次數:用在要指定其出現的次數的字符後面,用於限制其前面字符出現的次數;默認工作貪婪模式;
?????????*:匹配前面的字符任意次;0,1,多次;
?????????.*:匹配任意長度的任意字符;
?????????\?:匹配其前面的字符0次或1次;即前面的字符是可有可無的;
		?\+:匹配其面前的字符1次或多次;即前面的字符至少要出現一次;
		?\{m\}:匹配其前面的字符m次(精確匹配);
		?\{m,n\}:匹配其前面的字符至少m次,至多n次;
		????\{0,n\}:至多n次;
		????\{m,\}:至少m次;
??????位置錨定:
?????????^:行首錨定,用於模式的最左側;
?????????$:行尾錨定,用於模式的最右側;
?????????^PATTERN:用PATTERN來匹配整行;
????????????^$:空白行;
????????????^[[:space:]]*$:空行或包含空白字符的行;

??我們不僅僅在行的位置上來進行錨定,也能在單詞的位置上來進行錨定,那麽什麽是單詞,以及匹配的基本正則表達式的元字符是什麽,我們以下用來介紹:

???單詞:非特殊字符組成的連續字符(字符串)都稱之為單詞;

???\<?或?\b:詞首錨定,用於單詞模式的左側;
???\>?或?\b:詞尾錨定,用於單詞模式的右側;
???\<PATTERN\>:匹配完整單詞;

??好的,我們了解了上述的正則表達式以後,有以下的練習題可以參考以下:
??1、顯示/etc/passwd文件中不以/bin/bash結尾的行;

 ? # grep -v "/bin/bash$" /etc/passwd

??2、找出/etc/passwd文件中的兩位或三位數;

 ? # grep "[[:digit:]]\{2,3\}" /etc/passwd

??3、找出/etc/rc.d/rc.sysinit或/etc/grub2.cfg文件中,以至少一個空白字符開頭,且後面非空白字符的行;

 ? # grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg 

??4、找出"netstat -tan"命令中的結果以LISTEN後跟0、1或多個空白字符結尾的行;

 ? # netstat -tan | grep "LISTEN[[:space:]]*$"

??接下來開始說分組及引用,簡單來講是將一個或多個字符捆綁在一起,當作一個整體,而不是匹配單個字符,所以x和y要想一起匹配的話,就用括號給括起來,需要註意的是,括號在是由特殊用途,所以要轉義,轉義之後為:()。
??那麽分組完之後其實是可以引用的,引用就是將分組括號中的模式匹配到的內容會被正則表達式引擎自動記錄於內部變量中,那麽這些變量分別為:

???\1:要從左側起,第一個左括號以及與之匹配的右括號之間的模式所匹配到的字符;(引用第一個模式所匹配到的內容)
???\2:要從左側起,第二個左括號以及與之匹配的右括號之間的模式所匹配到的字符;
???\3:要從左側起,第三個左括號以及與之匹配的右括號之間的模式所匹配到的字符;
???...

??我們來做一下實例:

???He?likes?his?lover.
???He?loves?his?lover.
???She?likes?her?liker.
???She?lovers?her?liker.

???#?grep?"\(l..e\).*\1"?lover.txt

??而這就是後向引用,後向引用就是引用前面的分組括號中的模式,所匹配到的字符;需要註意的是:如果沒有分組的必要,但是有引用必要的話,也得加上括號,否則你不知道要引用那一段之間的內容。而用括號括起來不引用的話也只是為了做分組,所以括起來保存的結果是可以不引用的。


2017-12-9Linux基礎知識(16)文本處理工具