1. 程式人生 > >8.Linux的正規表示式與檔案格式化處理

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