8.Linux的正規表示式與檔案格式化處理
目錄
1.什麼是正規表示式?
正規表示法就是處理字串的一種方法,他是以行為單位來進行字串的處理行為, 正規表示法透過一些特殊符號的輔助,可以讓使用者輕易的達到『搜尋/刪除/取代』某特定字串的處理程式,能大大提高系統管理員的效率。
注意:正規表示法與萬用字元是完全不一樣的東西!因為『萬用字元 (wildcard) 代表的是 bash 操作介面的一個功能』,但正規表示法則是一種字串處理的表示方式!
2.基礎正規表示式
結合grep來學習正規表示式。
- 在正規表示式中,一個點 “.”代表一個任意字元的意思。
2.1.grep的一些進階階選項
語法:
grep [-A] [-B] [--color=auto] '搜尋字串' filename
選項
選項 | 含義 |
-A | 後面可加數字,為after的意思,除了列出該行外,後續的n行業列出來。 |
-B | 後面可加數字,為before的意思,除了列出該行外,前面的n行業列出 |
--color=auto | 關鍵詞的進行顏色標註 |
例子1:
複製:/etc/passwd檔案,到/test目錄下,然後編輯一下這個檔案:
編輯檔案:
使用grep命令擷取關鍵字gdm,使用命令:grep gdm passwd --color
正規表示式一個點就代表一個字元,也可以使用命令:grep 'g.m' passwd --color
解釋:在passwd檔案中找出d和m中有一個字母的字元的那一行,是什麼字母無所謂。
那如果找g和m當中有兩個字元的呢?使用命令:grep 'g..m' passwd --color
匹配到一行:
例子2:
再次修改一下passwd的檔案內容,再複製一行,把gdm改成其中一個是大寫的Gdm,試著一下使用命令:grep 'g.m' passwd --color,會不會找到這個關鍵詞的一行。
儲存退出編輯,使用命令:grep 'g.m' passwd --color
使用正規表示式忽字母G的大小寫怎麼做呢?
使用命令:grep '[Gg].m' passwd --color
例子3:
找到開頭為gdm的字串怎麼做呢?使用符號:"^"代表開頭的意思。
提示: "\<" 也可以表示開頭。
使用命令:grep '^gdm' passwd --color
例子4:
找到結尾有gdm這個字串怎麼做呢?使用符號:"$"代表結果的意思。
提示: "\>" 也可以表示結束。
使用命令:grep 'gdm$' passwd --color
例子5:限定連續字元範圍
比如你想尋找一個字串,gdddddddddddddm的話,我們可以發現裡面有13個d,當然你也可以直接使用grep去擷取,但是有一種更為便捷的命令:xy\{m\}z,表示xy中間有出現每個z的字串。
修改一下passwd這個檔案,具體來體驗一下這個含義:
分別查詢gm中間有6,8,10個d的字串:
使用命令:grep 'gd\{6\}m' passwd --color
尋找gm當中d的個數有6到11個之間的字串:
使用命令:grep 'gd\{6,11\}m' passwd --color
尋找gm當中d的個數大於3個的字串:
使用命令:grep 'gd\{3,\}m' passwd --color
3.sed工具
功能:sed 本身也是一個管線命令,可以分析 standard input ! 而且 sed還可以將資料進行取代、刪除、新增、擷取特定行等等的功能。
語法:
sed [-nefr] [動作]
選項
選型 | 含義 |
-n | 使用lilent模式,在一般sed的用法中,所有來自STDIN的資料一般都會被列到螢幕上,如果加上-n引數後,則只有經過sed特殊處理的那一行或者動作才會被列出來。 |
-e |
直接在指令列模式上進行sed的動作編輯,同時多多個操作。 例子,比如替換檔案的bin為大寫,還要替換檔案的usr為大寫,使用命令:sed -e 's/usr/USR/g' -e 's/bin/BIN/g' aa |
-f | 直接將sed的動作寫在一個檔案內,-f filename 則可以執行filename內的sed動作。 |
-r | sed的動作支援的是延伸型正規表示的語法。(預設是基礎正規比表示法語法)。 |
-i | 直接修改讀取檔案的內容,而不是由螢幕輸出。 |
動作說明:[n1[,n2]]function 解釋:n1,n2:不一定需要,表示選擇進行動作的函式,舉例子來說,如果我們動作需要在1-10行之內進行的話,則是:[1,10[動作行為]] |
|
function 的引數功能 | |
c | 替換,a後面可以接字串,替換掉含有目標字串的一行 |
d | 刪除,後面不跟任何東西。 |
i | 插入,i後面可以接字串,而這些字串會在新的一行出現(以現在為基準的下一行)。 |
a | 插入,i後面可以接字串,而這些字串會在新的一行出現(以現在為基準的上一行)。 |
p | 列印,將某個選擇的資料列印,通常會與引數sed -n 一起使用 |
s | 取代,可以直接進行取代工作。 |
例子1:
複製:/etc 下的hosts檔案,到、/test 目錄下,然後使用sed 刪除第一行和第二行。
使用命令: sed '1,2d' hosts
解釋:對第一行和第二行進行操作,動作是刪除,注意,這並沒有修改原始檔,只是把結果顯示在螢幕上。
如果想直接寫入檔案裡面,而不是顯示在螢幕上面怎麼做,使用引數:-i
使用命令: sed -i '1,2d' hosts
刪除最後一行,使用命令:sed '$d' hosts
例子2:替換
複製:/etc 下的passwd檔案的頭五行,到/test目錄下的aa檔案
使用命令:head -5 /etc/passwd > aa
把這個檔案額所有usr字元換成大寫的。
使用命令:sed 's/usr/USR/g' aa
例子3:連續替換,使用 -e 選項
複製:/etc 下的passwd檔案的頭五行,到/test目錄下的aa檔案
使用命令:sed -e 's/usr/USR/g' -e 's/bin/BIN/g' aa
例子4:
使用aa檔案,找到含有sys的一行,然後再他的上一行新增字串“mmmmmmmmmmmmmm”
使用命令:sed '/sys/i mmmmmmmmmmmmmmm' aa
例子5:
使用aa檔案,找到含有sys的一行,然後把這一行替換成字元“mmmmmmmmmmmmmm”
使用命令:sed '/sys/c mmmmmmmmmmmmmmm' aa
例子6:我們可以把我們所要做的一些操作寫入一個檔案裡,然後執行這個檔案的內容,就可以做相應的修改。
比如,1.找到有找到含有sys的一行,然後再他的上一行新增字串“mmmmmmmmmmmmmm”,2.找到含有sys的一行,然後再他的下一行新增字串“mmmmmmmmmmmmmm”3.把usr全部改大寫的 4.把bin全部改成大寫的。
首先新建一個檔案,命名為:changefile
然後編輯如下:
接著使用 -f 引數呼叫剛才的changefile 檔案
使用命令:sed -f changefile aa
解釋:修改的檔案為a,使用的命令為:sed,改變的指令從changefile裡面取用。
4.awk:好用的資料處理工具
功能:awk 也是一個非常棒的資料處理工具!相較於 sed 常常作用於一整個行的處理, awk 則比較傾向於一行當中分成數『欄位』來處理。因此,awk 相當的適合處理小型的資料處理。從一個檔案裡面找到感興趣的內容,然後進行重新排版。
語法
awk '條件型別 1{動作 1} 條件型別 2{動作 2} ...' filename
提示:awk 主要是處理『每一行的欄位內的資料』,而預設的『欄位的分隔符為 "空格" 或 "[tab]鍵" 』(使用-F可以指令分隔符),如果讀出一行沒有空格或者tab鍵的話,awk會認為這是一部分,不會把這一行進行分割。
例如我有一個檔案,裡面的內容如下,那麼具體的關係就如下圖
awk內建變數
變數 | 含義 |
NF | 每一行($0)擁有的欄位數 |
NR | 目前awk所處理的是第幾行資料 |
FS | 目前的分隔符,預設是空格 |
awk邏輯運算字元
運算單元 | 含義 |
> | 大於 |
< | 小於 |
>= | 大於或等於 |
<= | 小於或等於 |
== | 等於 |
!= | 不等於 |
例子1:內建變數的使用
例子2:使用$0顯示的是每一行的名字,不進行分段
例子3:
我們看看網絡卡配置的檔案:
如果我僅僅想提出檔案標註位置的數字:1,如何做呢?
首先,使用管道傳輸結果,然後提取有inet6的一行:
使用命令:ifconfig | grep 'inet6'
得到的結果再次通過管道傳輸給awk,預設使用空格作為分隔符,那我們取他的第二段出來,然後列印,得到結果:
使用命令:ifconfig | grep 'inet6' | awk '{print $2}'
我們需要提取到的是1,那麼再次通過管道傳輸給awk,這次需要指定分隔符,使用冒號為分隔符,然後提取第3個欄位的資料:
使用命令:ifconfig | grep 'inet6'|awk '{print $2}' |awk -F : '{print $3}'
例子4:如果想得到date這個命令的秒數
使用命令:date|awk '{print $4}'|awk -F: '{print $3}'
例子5:使用條件進行匹配
先看看aa檔案的內容:
我列印第一個欄位的內容,如果使用命令:awk -F: '{print $1}' aa,那麼所有第一欄位都會顯示出來
現在我需要匹配一個條件:就是第三個欄位小於等於2的那一行的第一欄位我才回顯示出來。
使用命令:awk -F: '$3<=2{print $1}' aa
例子6:使用自定義格式檢視檔案
現在看以西a檔案的內容,現在這樣子看起來好像很亂,因為說有的內容都是貼在一起的,那如何變得容易看呢:
假如我想要欄位之間使用tab鍵分開,然後行之間使用兩個空格鍵分開,然後只檢視前四個欄位,怎麼做呢?
提示:使用OFS可以指令欄位之間的間隔,使用ORS可以指定行之間的間隔。
使用命令:awk -F: 'BEGIN{OFS="\t";ORS="\n\n"}{print $1,$2,$3,$4}' aa
這樣子看起來是不是清晰明瞭了呢。
5.diff工具:檢視檔案的差異
語法:
diff [-bBi] from-file to-file
注意:from -file一個檔案名,原始對比檔案,to-file作為目的對比檔案
選項
選項 | 含義 |
-b | 忽略一行當中,僅有多個空白的差異。 |
-B | 忽略行與行之間空白的差異 |
-i | 忽略大小寫的不同 |
例子:
接著上面的aa檔案,然後把aa檔案複製一下,命名為bb,然後比較一下兩個的內容是不是一樣
使用命令:diff aa bb
沒有任何提示就是一樣的
現在修改一下bb的內容:
再次使用命令:diff aa bb