linux-basic(12)正则表达式与文件格式化处理
生活随笔
收集整理的這篇文章主要介紹了
linux-basic(12)正则表达式与文件格式化处理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【12.1.1】什么是正則表達式?
1)簡單說:正則表示法就是處理字串的方法,他是以行為單位來進行字串的處理行為, 正則表達式透過一些特殊符號的輔助,可以讓使用者輕易的達到查找、刪除、替換某特定字串的處理程序!
【12.1.5】擴展的正則表達式
正則表達式的字串表示方式依照不同的嚴謹度而分為: 基礎正則表達式與擴展正則表達式。
【12.2】基礎正則表達式
【12.2.1】語系對正則表達式的影響
1) 舉例來說,在英文大小寫的編碼順序中,zh_TW.big5 及 C 這兩種語系的輸出結果分別如下:
? ● LANG=C? ? ?時:0 1 2 3 4 ... A B C D ... Z a b c d ...z
? ● LANG=zh_TW 時:0 1 2 3 4 ... a A b B c C d D ... z Z
2)為了要避免這樣編碼所造成的英文與數字的擷取問題,因此有些特殊的符號我們得要了解一下的! 這些符號主要有底下這些意義:
(1)
【12.2.2】grep的一些高級參數
(2)
【荔枝】
(3)
補充1:grep 是一個很常見也很常用的命令,他最重要的功能就是進行字串數據的比對,然后將符合使用者需求的字串列印出來。 需要說明的是 grep 在數據中查尋一個字串時,是以 "整行" 為單位來進行數據的擷取的!
補充2:你可以在 ~/.bashrc 內加上這行:『alias grep='grep --color=auto'』再以『 source ~/.bashrc 』來立即生效即可喔! 這樣每次運行 grep 他都會自動幫你加上顏色顯示啦!
(4)
(5)
【12.2.3】基礎正則表達式練習
1)底下的練習大前提是:
? ● 語系已經使用『 export LANG=C 』的配置值;
? ● grep 已經使用 alias 配置成為『 grep --color=auto 』
2)regular_express.txt 內容如下:?
"Open Source" is a good mechanism to develop programs. apple is my favorite food. Football game is not use feet only. this dress doesn't fit me. However, this dress is about $ 3183 dollars. GNU is free air not free beer. Her hair is very beauty. I can't finish the test. Oh! The soup taste good. motorcycle is cheap than car. This window is clear. the symbol '*' is represented as start. Oh! My god! The gd software is a library for drafting programs. You are the best is mean you are the no. 1. The world <Happy> is the same with "glad". I like dog. google is the best tools for search keyword. goooooogle yes! go! go! Let's go. # I am VBird【荔枝1】在文件中搜索the這個字符串所在的數據行;
(6)
【荔枝2】反向選擇;
(7)
(8)
【荔枝】 利用中括號 [] 來搜索集合字節
(9)
(10)
(11)
【繼續荔枝】假設我 oo 前面不想要有小寫字節,所以,我可以這樣寫 [^abcd....z]oo , 但是這樣似乎不怎么方便,由於小寫字節的 ASCII 上編碼的順序是連續的, 因此,我們可以將之簡化為底下這樣:
(12)
(13)
(14)
(15)
【荔枝3】行首與行尾字符 ^$
(16)
(17)
(18)
(19)
【注意】^ 在中括號[] 外面表示行首,在中括號里面表示取反或非;
(20)
【注意】
注意1:上荔枝中 用 反斜杠 \ 對 點符號. 進行了轉義;
注意2:你或許會覺得奇怪,但是第 5~9 行最后面也是 . 啊~怎么無法列印出來? 這里就牽涉到 Windows 平臺的軟件對於斷行字節的判斷問題了!我們使用 cat -A 將第五行拿出來看, 你會發現:
(21)
在上面的表格中我們可以發現 5~9 行為 Windows 的斷行字節 (^M$) ,而正常的 Linux 應該僅有第 10 行顯示的那樣 ($) 。所以羅,那個 . 自然就不是緊接在 $ 之前喔!也就捉不到 5~9 行了!
(22)
(23)
【荔枝4】任意一個字節. 與重復字節*
這兩個符號在正規表示法的意義如下:
? ● . (小數點):代表『一定有一個任意字節』的意思;
? ● * (星星號):代表『重復前一個字節, 0 到無窮多次』的意思,為組合形態
場景1)假設我需要找出 g??d 的字串,亦即共有四個字節, 起頭是 g 而結束是 d ,我可以這樣做:
(24)
補充1)因為 * 代表的是『重復 0 個或多個前面的 RE 字符』的意義, 因此,『o*』代表的是:『擁有空字節或一個 o 以上的字節』, 特別注意,因為允許空字節(就是有沒有字節都可以的意思),因此,『 grep -n 'o*' regular_express.txt 』將會把所有的數據都列印出來螢幕上!
補充2)那如果是『oo*』呢?則第一個 o 肯定必須要存在,第二個 o 則是可有可無的多個 o , 所以,凡是含有 o, oo, ooo, oooo 等等,都可以被列出來~
補充3)同理,當我們需要『至少兩個 o 以上的字串』時,就需要 ooo* ,亦即是:
(25)
(26)
(27)
(28)
【荔枝5】限定連續 正則表達式 字符范圍 {}
在上個例題當中,我們可以利用 . 與 RE 字符及 * 來配置 0 個到無限多個重復字節, 那如果我想要限制一個范圍區間內的重復字節數呢?舉例來說,我想要找出兩個到五個 o 的連續字串,該如何作?這時候就得要使用到限定范圍的字符 {} 了。 但因為 { 與 } 的符號在 shell 是有特殊意義的,因此, 我們必須要使用跳脫字符 \ 來讓他失去特殊意義才行。?
場景1)至於 {} 的語法是這樣的,假設我要找到兩個 o 的字串,可以是:
(29)
(30)
(31)
【12.2.4】基礎正則表達式字符
1)基礎的正規表示法特殊字符匯整如下:
(32)
注意1:再次強調:『正則表達式的特殊字節』與一般在命令列輸入命令的通配符并不相同, 例如,在通配符中的 * 代表的是『 0 ~ 無限多個字節』的意思,但是在正則表達式當中, * 則是『重復 0 到無窮多個的前一個 RE 字符』的意思。
【12.2.5】sed工具
1)sed 本身也是一個管線命令,可以分析 standard input 的啦! 而且 sed 還可以將數據進行取代、刪除、新增、擷取特定行等等的功能呢!
(33)
2)以行為單位的新增/刪除功能
(34)
補充:如果題型變化一下,舉例來說,如果只要刪除第 2 行,可以使用『 nl /etc/passwd | sed '2d' 』來達成, 至於若是要刪除第 3 到最后一行,則是『 nl /etc/passwd | sed '3,$d' 』的啦,那個錢字號『 $ 』代表最后一行!
(35)
補充:在 a 后面加上的字串就已將出現在第二行后面羅!那如果是要在第二行前呢?『 nl /etc/passwd | sed '2i drink tea' 』就對啦!就是將『 a 』變成『 i 』即可。?
【繼續荔枝】:添加一行很簡單,那如果是要增將兩行以上呢?
(36)
3)以行為單位的取代與顯示功能
(37)
(38)
(39)
4)部分數據的搜尋并取代的功能
除了整行的處理模式之外, sed 還可以用行為單位進行部分數據的搜尋并取代的功能喔! 基本上 sed 的搜尋與取代的與 vi 相當的類似!他有點像這樣:sed 's/要被取代的字串/新的字串/g'
【荔枝】 文本內容如下:
(40)
(41)
(42)
(43)
(44)
【繼續荔枝】假設我只要 MAN 存在的那幾行數據, 但是含有 # 在內的注解我不想要,而且空白行我也不要!此時該如何處理呢?可以透過這幾個步驟來實作看看:
(45)
(46)
(47)
空白行:包括有空格符的空白行,沒有空格符的空白行;
5)直接修改文件內容(危險操作): sed 甚至可以直接修改文件的內容呢!而不必使用管線命令或數據流重導向! 不過,由於這個動作會直接修改到原始的文件,所以請你千萬不要隨便拿系統配置檔來測試喔! 我們還是使用你下載的 regular_express.txt 文件來測試看看吧!
(48)
(49)
sed 的『 -i 』選項可以直接修改文件內容,這功能非常有幫助!舉例來說,如果你有一個 100 萬行的文件,你要在第 100 行加某些文字,此時使用 vim 可能會瘋掉!因為文件太大了!那怎辦?就利用 sed 啊!透過 sed 直接修改/取代的功能,你甚至不需要使用 vim 去修訂!很棒吧!
【12.3】擴展正則表達式
1)為什么需要擴展正則表達式? 舉個簡單的例子好了,在上節的例題三的最后一個例子中,我們要去除空白行與行首為 # 的行列,使用的是
grep -v '^$' regular_express.txt | grep -v '^#'
需要使用到管線命令來搜尋兩次!那么如果使用延伸型的正規表示法,我們可以簡化為:
egrep -v '^$|^#' regular_express.txt
2)擴展正則表達式可以透過群組功能『 | 』來進行一次搜尋!那個在單引號內的管線意義為『或 or』啦! 是否變的更簡單呢?此外,grep 默認僅支持基礎正規表示法,如果要使用延伸型正規表示法,你可以使用 grep -E , 不過更建議直接使用 egrep !直接區分命令比較好記憶!其實 egrep 與 grep -E 是類似命令別名的關系啦!
3)擴展型正則表達式有哪幾個特殊符號呢?
(50)
【荔枝】
(51)
(52)
(53)
(54)
(55)
【12.4】文件的格式化與相關處理
【12.4.1】格式化打印: printf
(56)
【荔枝】
(57)
補充: 在 printf 后續的那一段格式中,%s 代表一個不固定長度的字串,而字串與字串中間就以 \t 這個 [tab] 分隔符號來處理!你要記得的是,由於 \t 與 %s 中間還有空格,因此每個字串間會有一個 [tab] 與一個空白鍵的分隔喔!
(58)
補充:上面的格式共分為五個欄位, %10s 代表的是一個長度為 10 個字節的字串欄位,%5i 代表的是長度為 5 個字節的數字欄位,至於那個 %8.2f 則代表長度為 8 個字節的具有小數點的欄位,其中小數點有兩個字節寬度。我們可以使用底下的說明來介紹 %8.2f 的意義:
字節寬度: 12345678
%8.2f意義:00000.00
如上所述,全部的寬度僅有 8 個字節,整數部分占有 5 個字節,小數點本身 (.) 占一位,小數點下的位數則有兩位。
【繼續荔枝】printf 除了可以格式化處理之外,他還可以依據 ASCII 的數字與圖形對應來顯示數據喔(注3)! 舉例來說 16 進位的 45 可以得到什么 ASCII 的顯示圖 (其實是字節啦)?
(59)
16進制45 = 16*4+5 = 69, 而65~90 = A~Z;所以69表示E;
【12.4.2】awk:好用的數據處理工具
1)相較於 sed 常常作用於一整個行的處理,awk 則比較傾向於一行當中分成數個『欄位』來處理。因此,awk 相當的適合處理小型的數據數據處理呢!
2)awk 通常運行的模式是這樣的:??
[root@www ~]# awk '條件類型1{動作1} 條件類型2{動作2} ...' filename
awk 后面接兩個單引號并加上大括號 {} 來配置想要對數據進行的處理動作。 awk 可以處理后續接的文件,也可以讀取來自前個命令的 standard output 。
總結:awk 主要是處理『每一行的欄位內的數據』,而默認的『欄位的分隔符號為 "空白鍵" 或 "[tab]鍵" 』;
【荔枝】
(60)
分析1:由上面這個例子你也會知道,在每一行的每個欄位都是有變量名稱的,那就是 $1, $2... 等變量名稱。$0 代表『一整列數據』的意思~。
分析2:上述荔枝的整個 awk 的處理流程是:
? 1. 讀入第一行,并將第一行的數據填入 $0, $1, $2.... 等變量當中;
? 2. 依據 "條件類型" 的限制,判斷是否需要進行后面的 "動作";
? 3. 做完所有的動作與條件類型;
? 4. 若還有后續的『行』的數據,則重復上面 1~3 的步驟,直到所有的數據都讀完為止。
經過這樣的步驟,你會曉得, awk 是『以行為一次處理的單位』, 而『以欄位為最小的處理單位』。
3)awk 怎么知道我到底這個數據有幾行?有幾欄呢?這就需要 awk 的內建變量的幫忙啦~
(61)
【荔枝】我們繼續以上面 last -n 5 的例子來做說明,如果我想要:
? ● 列出每一行的帳號(就是 $1);
? ● 列出目前處理的行數(就是 awk 內的 NR 變量)
? ● 并且說明,該行有多少欄位(就是 awk 內的 NF 變量)
則可以這樣:
(62)
4)awk的邏輯運算符
(63)
【荔枝——利用 BEGIN 命令來預設了 awk變量】那假設我要查閱,第三欄小於 5 以下的數據,并且僅列出帳號與第三欄, 那么可以這樣做:
(64)
有個問題:怎么第1行沒有正確顯示出來呢?
這是因為我們讀入第一行的時候,那些變量 $1, $2... 默認還是以空白鍵為分隔的,所以雖然我們定義了 FS=":" 了, 但是卻僅能在第二行后才開始生效。那么怎么辦呢?我們可以預先配置 awk 的變量啊! 利用 BEGIN 這個關鍵字喔!這樣做:
(65)
干貨:這里利用 BEGIN 命令來預設了 awk變量;
【荔枝】利用awk來進行計算功能。對如下薪資表求總和:
[root@localhost chapter12]# cat pay.txt Name 1st 2nd 3th VBird 23000 24000 25000 DMTsai 21000 20000 23000 Bird2 43000 42000 41000求和說明:我們可以這樣考慮:
? ● 第一行只是說明,所以第一行不要進行加總 (NR==1 時處理);
? ● 第二行以后就會有加總的情況出現 (NR>=2 以后處理)
(66)
上面的例子有幾個重要事項應該要先說明的:
? ● awk 的命令間隔:所有 awk 的動作,亦即在 {} 內的動作,如果有需要多個命令輔助時,可利用分號『;』間隔, 或者直接以 [Enter] 按鍵來隔開每個命令,例如上面的范例中,鳥哥共按了三次 [enter] 喔!
? ● 邏輯運算當中,如果是『等於』的情況,則務必使用兩個等號『==』!
? ● 格式化輸出時,在 printf 的格式配置當中,務必加上 \n ,才能進行分行!
? ● 與 bash shell 的變量不同,在 awk 當中,變量可以直接使用,不需加上 $ 符號。
(67)
cat pay.txt | awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1, $2, $3, $4, "total"};
NR>=2 {total=$2+$3+$4;
printf "%10s %10d %10d %10d %10.2f\n",$1, $2, $3, $4, total}'
【繼續荔枝】另外, awk 的動作內 {} 也是支持 if (條件) 的喔! 舉例來說,上面的命令可以修訂成為這樣:
(68)
cat pay.txt | awk '{if(NR==1) printf "%10s %10s %10s %10s %10s\n",$1, $2, $3, $4, "total"};
{if(NR>=2) total=$2+$3+$4;
printf "%10s %10d %10d %10d %10.2f\n",$1, $2, $3, $4, total}'
總結: 第1種統計方法比較常用;
【12.4.3】文件比較工具
1)diff 命令:通常是用在同一的文件(或軟件)的新舊版本差異上!
(69)
【荔枝】假如我們要將 /etc/passwd 處理成為一個新的版本,處理方式為: 將第四行刪除,第六行則取代成為『no six line』,新的文件放置到 /tmp/test 里面,那么應該怎么做?
(70)
(71)
【繼續荔枝】另外, diff 也可以比對整個目錄下的差異喔!舉例來說,我們想要了解一下不同的啟動運行等級 (runlevel) 內容有啥不同?假設你已經知道運行等級 3 與 5 的啟動腳本分別放置到 /etc/rc3.d 及 /etc/rc5.d , 則我們可以將兩個目錄比對一下:
(72)
2)cmp命令: cmp 主要也是在比對兩個文件,他主要利用字節單位去比對, 因此,當然也可以比對 binary file 羅~(還是要再提醒喔, diff 主要是以『行』為單位比對, cmp 則是以字節為單位去比對,這并不相同!)
(73)
【荔枝】
(74)
3)cmp命令: diff 可以用來分辨兩個版本之間的差異, 舉例來說,剛剛我們所創建的 passwd.old 及 passwd.new 之間就是兩個不同版本的文件。 那么,如果要『升級』呢?就是『將舊的文件升級成為新的文件』時,應該要怎么做呢? 其實也不難啦!就是『先比較先舊版本的差異,并將差異檔制作成為補丁檔,再由補丁檔升級舊文件』即可。 舉例來說,我們可以這樣做測試:
(75)
(76)
補充:? 以上面表格為例,新文件看到 - 會刪除,看到 + 會加入!好了,那么如何將舊的文件升級成為新的內容呢? 就是將 passwd.old 改成與 passwd.new 相同!可以這樣做:
(77)
(78)
(79)
【12.4.4】文件打印準備:pr
1) 如果我是在 Linux 底下列印純文字檔呢 可不可以具有標題啊?可不可以加入頁碼啊?呵呵!當然可以啊!使用 pr 就能夠達到這個功能了。
【荔枝】舉例來說,如果想要列印 /etc/man.config 呢?
(80)
1)簡單說:正則表示法就是處理字串的方法,他是以行為單位來進行字串的處理行為, 正則表達式透過一些特殊符號的輔助,可以讓使用者輕易的達到查找、刪除、替換某特定字串的處理程序!
【12.1.5】擴展的正則表達式
正則表達式的字串表示方式依照不同的嚴謹度而分為: 基礎正則表達式與擴展正則表達式。
【12.2】基礎正則表達式
【12.2.1】語系對正則表達式的影響
1) 舉例來說,在英文大小寫的編碼順序中,zh_TW.big5 及 C 這兩種語系的輸出結果分別如下:
? ● LANG=C? ? ?時:0 1 2 3 4 ... A B C D ... Z a b c d ...z
? ● LANG=zh_TW 時:0 1 2 3 4 ... a A b B c C d D ... z Z
2)為了要避免這樣編碼所造成的英文與數字的擷取問題,因此有些特殊的符號我們得要了解一下的! 這些符號主要有底下這些意義:
(1)
【12.2.2】grep的一些高級參數
(2)
【荔枝】
(3)
補充1:grep 是一個很常見也很常用的命令,他最重要的功能就是進行字串數據的比對,然后將符合使用者需求的字串列印出來。 需要說明的是 grep 在數據中查尋一個字串時,是以 "整行" 為單位來進行數據的擷取的!
補充2:你可以在 ~/.bashrc 內加上這行:『alias grep='grep --color=auto'』再以『 source ~/.bashrc 』來立即生效即可喔! 這樣每次運行 grep 他都會自動幫你加上顏色顯示啦!
(4)
(5)
【12.2.3】基礎正則表達式練習
1)底下的練習大前提是:
? ● 語系已經使用『 export LANG=C 』的配置值;
? ● grep 已經使用 alias 配置成為『 grep --color=auto 』
2)regular_express.txt 內容如下:?
"Open Source" is a good mechanism to develop programs. apple is my favorite food. Football game is not use feet only. this dress doesn't fit me. However, this dress is about $ 3183 dollars. GNU is free air not free beer. Her hair is very beauty. I can't finish the test. Oh! The soup taste good. motorcycle is cheap than car. This window is clear. the symbol '*' is represented as start. Oh! My god! The gd software is a library for drafting programs. You are the best is mean you are the no. 1. The world <Happy> is the same with "glad". I like dog. google is the best tools for search keyword. goooooogle yes! go! go! Let's go. # I am VBird【荔枝1】在文件中搜索the這個字符串所在的數據行;
(6)
【荔枝2】反向選擇;
(7)
(8)
【荔枝】 利用中括號 [] 來搜索集合字節
(9)
(10)
(11)
【繼續荔枝】假設我 oo 前面不想要有小寫字節,所以,我可以這樣寫 [^abcd....z]oo , 但是這樣似乎不怎么方便,由於小寫字節的 ASCII 上編碼的順序是連續的, 因此,我們可以將之簡化為底下這樣:
(12)
(13)
(14)
(15)
【荔枝3】行首與行尾字符 ^$
(16)
(17)
(18)
(19)
【注意】^ 在中括號[] 外面表示行首,在中括號里面表示取反或非;
(20)
【注意】
注意1:上荔枝中 用 反斜杠 \ 對 點符號. 進行了轉義;
注意2:你或許會覺得奇怪,但是第 5~9 行最后面也是 . 啊~怎么無法列印出來? 這里就牽涉到 Windows 平臺的軟件對於斷行字節的判斷問題了!我們使用 cat -A 將第五行拿出來看, 你會發現:
(21)
在上面的表格中我們可以發現 5~9 行為 Windows 的斷行字節 (^M$) ,而正常的 Linux 應該僅有第 10 行顯示的那樣 ($) 。所以羅,那個 . 自然就不是緊接在 $ 之前喔!也就捉不到 5~9 行了!
(22)
(23)
【荔枝4】任意一個字節. 與重復字節*
這兩個符號在正規表示法的意義如下:
? ● . (小數點):代表『一定有一個任意字節』的意思;
? ● * (星星號):代表『重復前一個字節, 0 到無窮多次』的意思,為組合形態
場景1)假設我需要找出 g??d 的字串,亦即共有四個字節, 起頭是 g 而結束是 d ,我可以這樣做:
(24)
補充1)因為 * 代表的是『重復 0 個或多個前面的 RE 字符』的意義, 因此,『o*』代表的是:『擁有空字節或一個 o 以上的字節』, 特別注意,因為允許空字節(就是有沒有字節都可以的意思),因此,『 grep -n 'o*' regular_express.txt 』將會把所有的數據都列印出來螢幕上!
補充2)那如果是『oo*』呢?則第一個 o 肯定必須要存在,第二個 o 則是可有可無的多個 o , 所以,凡是含有 o, oo, ooo, oooo 等等,都可以被列出來~
補充3)同理,當我們需要『至少兩個 o 以上的字串』時,就需要 ooo* ,亦即是:
(25)
(26)
(27)
(28)
【荔枝5】限定連續 正則表達式 字符范圍 {}
在上個例題當中,我們可以利用 . 與 RE 字符及 * 來配置 0 個到無限多個重復字節, 那如果我想要限制一個范圍區間內的重復字節數呢?舉例來說,我想要找出兩個到五個 o 的連續字串,該如何作?這時候就得要使用到限定范圍的字符 {} 了。 但因為 { 與 } 的符號在 shell 是有特殊意義的,因此, 我們必須要使用跳脫字符 \ 來讓他失去特殊意義才行。?
場景1)至於 {} 的語法是這樣的,假設我要找到兩個 o 的字串,可以是:
(29)
(30)
(31)
【12.2.4】基礎正則表達式字符
1)基礎的正規表示法特殊字符匯整如下:
(32)
注意1:再次強調:『正則表達式的特殊字節』與一般在命令列輸入命令的通配符并不相同, 例如,在通配符中的 * 代表的是『 0 ~ 無限多個字節』的意思,但是在正則表達式當中, * 則是『重復 0 到無窮多個的前一個 RE 字符』的意思。
【12.2.5】sed工具
1)sed 本身也是一個管線命令,可以分析 standard input 的啦! 而且 sed 還可以將數據進行取代、刪除、新增、擷取特定行等等的功能呢!
(33)
2)以行為單位的新增/刪除功能
(34)
補充:如果題型變化一下,舉例來說,如果只要刪除第 2 行,可以使用『 nl /etc/passwd | sed '2d' 』來達成, 至於若是要刪除第 3 到最后一行,則是『 nl /etc/passwd | sed '3,$d' 』的啦,那個錢字號『 $ 』代表最后一行!
(35)
補充:在 a 后面加上的字串就已將出現在第二行后面羅!那如果是要在第二行前呢?『 nl /etc/passwd | sed '2i drink tea' 』就對啦!就是將『 a 』變成『 i 』即可。?
【繼續荔枝】:添加一行很簡單,那如果是要增將兩行以上呢?
(36)
3)以行為單位的取代與顯示功能
(37)
(38)
(39)
4)部分數據的搜尋并取代的功能
除了整行的處理模式之外, sed 還可以用行為單位進行部分數據的搜尋并取代的功能喔! 基本上 sed 的搜尋與取代的與 vi 相當的類似!他有點像這樣:sed 's/要被取代的字串/新的字串/g'
【荔枝】 文本內容如下:
(40)
(41)
(42)
(43)
(44)
【繼續荔枝】假設我只要 MAN 存在的那幾行數據, 但是含有 # 在內的注解我不想要,而且空白行我也不要!此時該如何處理呢?可以透過這幾個步驟來實作看看:
(45)
(46)
(47)
空白行:包括有空格符的空白行,沒有空格符的空白行;
5)直接修改文件內容(危險操作): sed 甚至可以直接修改文件的內容呢!而不必使用管線命令或數據流重導向! 不過,由於這個動作會直接修改到原始的文件,所以請你千萬不要隨便拿系統配置檔來測試喔! 我們還是使用你下載的 regular_express.txt 文件來測試看看吧!
(48)
(49)
sed 的『 -i 』選項可以直接修改文件內容,這功能非常有幫助!舉例來說,如果你有一個 100 萬行的文件,你要在第 100 行加某些文字,此時使用 vim 可能會瘋掉!因為文件太大了!那怎辦?就利用 sed 啊!透過 sed 直接修改/取代的功能,你甚至不需要使用 vim 去修訂!很棒吧!
【12.3】擴展正則表達式
1)為什么需要擴展正則表達式? 舉個簡單的例子好了,在上節的例題三的最后一個例子中,我們要去除空白行與行首為 # 的行列,使用的是
grep -v '^$' regular_express.txt | grep -v '^#'
需要使用到管線命令來搜尋兩次!那么如果使用延伸型的正規表示法,我們可以簡化為:
egrep -v '^$|^#' regular_express.txt
2)擴展正則表達式可以透過群組功能『 | 』來進行一次搜尋!那個在單引號內的管線意義為『或 or』啦! 是否變的更簡單呢?此外,grep 默認僅支持基礎正規表示法,如果要使用延伸型正規表示法,你可以使用 grep -E , 不過更建議直接使用 egrep !直接區分命令比較好記憶!其實 egrep 與 grep -E 是類似命令別名的關系啦!
3)擴展型正則表達式有哪幾個特殊符號呢?
(50)
【荔枝】
(51)
(52)
(53)
(54)
(55)
【12.4】文件的格式化與相關處理
【12.4.1】格式化打印: printf
(56)
【荔枝】
(57)
補充: 在 printf 后續的那一段格式中,%s 代表一個不固定長度的字串,而字串與字串中間就以 \t 這個 [tab] 分隔符號來處理!你要記得的是,由於 \t 與 %s 中間還有空格,因此每個字串間會有一個 [tab] 與一個空白鍵的分隔喔!
(58)
補充:上面的格式共分為五個欄位, %10s 代表的是一個長度為 10 個字節的字串欄位,%5i 代表的是長度為 5 個字節的數字欄位,至於那個 %8.2f 則代表長度為 8 個字節的具有小數點的欄位,其中小數點有兩個字節寬度。我們可以使用底下的說明來介紹 %8.2f 的意義:
字節寬度: 12345678
%8.2f意義:00000.00
如上所述,全部的寬度僅有 8 個字節,整數部分占有 5 個字節,小數點本身 (.) 占一位,小數點下的位數則有兩位。
【繼續荔枝】printf 除了可以格式化處理之外,他還可以依據 ASCII 的數字與圖形對應來顯示數據喔(注3)! 舉例來說 16 進位的 45 可以得到什么 ASCII 的顯示圖 (其實是字節啦)?
(59)
16進制45 = 16*4+5 = 69, 而65~90 = A~Z;所以69表示E;
【12.4.2】awk:好用的數據處理工具
1)相較於 sed 常常作用於一整個行的處理,awk 則比較傾向於一行當中分成數個『欄位』來處理。因此,awk 相當的適合處理小型的數據數據處理呢!
2)awk 通常運行的模式是這樣的:??
[root@www ~]# awk '條件類型1{動作1} 條件類型2{動作2} ...' filename
awk 后面接兩個單引號并加上大括號 {} 來配置想要對數據進行的處理動作。 awk 可以處理后續接的文件,也可以讀取來自前個命令的 standard output 。
總結:awk 主要是處理『每一行的欄位內的數據』,而默認的『欄位的分隔符號為 "空白鍵" 或 "[tab]鍵" 』;
【荔枝】
(60)
分析1:由上面這個例子你也會知道,在每一行的每個欄位都是有變量名稱的,那就是 $1, $2... 等變量名稱。$0 代表『一整列數據』的意思~。
分析2:上述荔枝的整個 awk 的處理流程是:
? 1. 讀入第一行,并將第一行的數據填入 $0, $1, $2.... 等變量當中;
? 2. 依據 "條件類型" 的限制,判斷是否需要進行后面的 "動作";
? 3. 做完所有的動作與條件類型;
? 4. 若還有后續的『行』的數據,則重復上面 1~3 的步驟,直到所有的數據都讀完為止。
經過這樣的步驟,你會曉得, awk 是『以行為一次處理的單位』, 而『以欄位為最小的處理單位』。
3)awk 怎么知道我到底這個數據有幾行?有幾欄呢?這就需要 awk 的內建變量的幫忙啦~
(61)
【荔枝】我們繼續以上面 last -n 5 的例子來做說明,如果我想要:
? ● 列出每一行的帳號(就是 $1);
? ● 列出目前處理的行數(就是 awk 內的 NR 變量)
? ● 并且說明,該行有多少欄位(就是 awk 內的 NF 變量)
則可以這樣:
(62)
4)awk的邏輯運算符
(63)
【荔枝——利用 BEGIN 命令來預設了 awk變量】那假設我要查閱,第三欄小於 5 以下的數據,并且僅列出帳號與第三欄, 那么可以這樣做:
(64)
有個問題:怎么第1行沒有正確顯示出來呢?
這是因為我們讀入第一行的時候,那些變量 $1, $2... 默認還是以空白鍵為分隔的,所以雖然我們定義了 FS=":" 了, 但是卻僅能在第二行后才開始生效。那么怎么辦呢?我們可以預先配置 awk 的變量啊! 利用 BEGIN 這個關鍵字喔!這樣做:
(65)
干貨:這里利用 BEGIN 命令來預設了 awk變量;
【荔枝】利用awk來進行計算功能。對如下薪資表求總和:
[root@localhost chapter12]# cat pay.txt Name 1st 2nd 3th VBird 23000 24000 25000 DMTsai 21000 20000 23000 Bird2 43000 42000 41000求和說明:我們可以這樣考慮:
? ● 第一行只是說明,所以第一行不要進行加總 (NR==1 時處理);
? ● 第二行以后就會有加總的情況出現 (NR>=2 以后處理)
(66)
上面的例子有幾個重要事項應該要先說明的:
? ● awk 的命令間隔:所有 awk 的動作,亦即在 {} 內的動作,如果有需要多個命令輔助時,可利用分號『;』間隔, 或者直接以 [Enter] 按鍵來隔開每個命令,例如上面的范例中,鳥哥共按了三次 [enter] 喔!
? ● 邏輯運算當中,如果是『等於』的情況,則務必使用兩個等號『==』!
? ● 格式化輸出時,在 printf 的格式配置當中,務必加上 \n ,才能進行分行!
? ● 與 bash shell 的變量不同,在 awk 當中,變量可以直接使用,不需加上 $ 符號。
(67)
cat pay.txt | awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1, $2, $3, $4, "total"};
NR>=2 {total=$2+$3+$4;
printf "%10s %10d %10d %10d %10.2f\n",$1, $2, $3, $4, total}'
【繼續荔枝】另外, awk 的動作內 {} 也是支持 if (條件) 的喔! 舉例來說,上面的命令可以修訂成為這樣:
(68)
cat pay.txt | awk '{if(NR==1) printf "%10s %10s %10s %10s %10s\n",$1, $2, $3, $4, "total"};
{if(NR>=2) total=$2+$3+$4;
printf "%10s %10d %10d %10d %10.2f\n",$1, $2, $3, $4, total}'
總結: 第1種統計方法比較常用;
【12.4.3】文件比較工具
1)diff 命令:通常是用在同一的文件(或軟件)的新舊版本差異上!
(69)
【荔枝】假如我們要將 /etc/passwd 處理成為一個新的版本,處理方式為: 將第四行刪除,第六行則取代成為『no six line』,新的文件放置到 /tmp/test 里面,那么應該怎么做?
(70)
(71)
【繼續荔枝】另外, diff 也可以比對整個目錄下的差異喔!舉例來說,我們想要了解一下不同的啟動運行等級 (runlevel) 內容有啥不同?假設你已經知道運行等級 3 與 5 的啟動腳本分別放置到 /etc/rc3.d 及 /etc/rc5.d , 則我們可以將兩個目錄比對一下:
(72)
2)cmp命令: cmp 主要也是在比對兩個文件,他主要利用字節單位去比對, 因此,當然也可以比對 binary file 羅~(還是要再提醒喔, diff 主要是以『行』為單位比對, cmp 則是以字節為單位去比對,這并不相同!)
(73)
【荔枝】
(74)
3)cmp命令: diff 可以用來分辨兩個版本之間的差異, 舉例來說,剛剛我們所創建的 passwd.old 及 passwd.new 之間就是兩個不同版本的文件。 那么,如果要『升級』呢?就是『將舊的文件升級成為新的文件』時,應該要怎么做呢? 其實也不難啦!就是『先比較先舊版本的差異,并將差異檔制作成為補丁檔,再由補丁檔升級舊文件』即可。 舉例來說,我們可以這樣做測試:
(75)
(76)
補充:? 以上面表格為例,新文件看到 - 會刪除,看到 + 會加入!好了,那么如何將舊的文件升級成為新的內容呢? 就是將 passwd.old 改成與 passwd.new 相同!可以這樣做:
(77)
(78)
(79)
【12.4.4】文件打印準備:pr
1) 如果我是在 Linux 底下列印純文字檔呢 可不可以具有標題啊?可不可以加入頁碼啊?呵呵!當然可以啊!使用 pr 就能夠達到這個功能了。
【荔枝】舉例來說,如果想要列印 /etc/man.config 呢?
(80)
總結
以上是生活随笔為你收集整理的linux-basic(12)正则表达式与文件格式化处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux-basic(11)认识和学习
- 下一篇: 论坛网站怎么推广(论坛网站怎么推广的)