鳥哥的linux私房菜——第12章 Regex與檔案格式化處理,linux私房菜
12.1什麼是Regex
Regex就是處理字串的方法,它是以行為單位來進行字串的處理行為,Regex通過一些特殊符號的輔助,可以讓使用者輕易達到尋找、刪除、替換某特定字串的處理常式。
vi、grep、awk、sed支援Regex,而cp,ls等命令只能使用bash自身的萬用字元
12.2基礎Regex
grep進階參數:
grep [-A] [-B] [--color=auto] 'string' filename
-A:after的意思,除了列出該行外,後續的n行也列出來
-B:before的意思,除了列出該行外,前面的n行也列出來
--color=auto 可將正確的那個選取資料列出顏色
基礎Regex練習:
例一:尋找特定字串
grep -n ‘the’ regular_express.txt
grep -vn 'the' regular_express.txt (-v反向選擇)
例二:利用中括弧[]來尋找集合字元
grep -n 't[ae]st' regular_express.txt (可匹配test或tast)
grep -n '[^g]oo' regular_express.txt (oo前不能有g的字元)
grep -n '[^[:lower:]]oo' regular_express.txt ([:lower:]代表a-z的意思)
例三:行首和行尾字元
grep -n '^test' regular_express.txt
(註:^在[]內表示“反向選擇”,在[]外表示定位在行首)
grep -n '\.$' regular_express.txt (找出行尾結束為小數點的那一行)
例四:任意一個字元.與重複字元*
grep -n ‘g..d’ regular_express.txt (可匹配good,glad等字元)
grep -n 'ooo*' regular_express.txt (匹配至少兩個o以上的字元)
grep -n 'g.*g' regular_express.txt (找出g開頭與g結尾的字串,.*表示o個或多個任一字元的意思)
例五:限定連續RE字元範圍{}
grep -n 'o\{2\}' regular_express.txt (找出兩個o的字串)
grep -n ‘go\{2,5\}g’ regular_express.txt (g後有兩個到5個o,然後接一個g的字串)
grep -n ‘go\{2,\}g’ regular_express.txt (g後有兩個及以上的o,然後接一個g的字串)
基礎Regex字元:
^word :待尋找的字串(word)在行首
word$ :待尋找的字串(word)在行尾
. :代表一定有一個任一字元的字元
\ : 逸出字元,將特殊符號的特殊意義去除
* : 重複0個或多個的前一個字元
[list] :從字元集合的RE字元裡面找出想要選取的字元
[n1-n2]:從字元集合的RE字元裡面找出想要選取的字元範圍
[^list] :從字元集合的RE字元裡面找出不要的字串或範圍
\{n,m\}:連續n到m個的前一個RE字元,\{n\}表示連續n個,\{n,\}表示連續n個及以上
sed工具:(詳見sed & awk)
格式:sed [-nefr] [動作]
參數:
-n :使用安靜模式,在一般的sed用法中,所有來自STDIN的資料一般都會被列到螢幕上,但如果加上-n參數後,則只有經過sed特殊處理的那一行才會被列出來
-e :直接在命令列模式上進行sed的動作編輯
-f :直接將sed的動作寫在一個檔案內,-f filename 則可以執行filename內的sed動作
-r :sed的動作支援的擴充型Regex的文法
-i :直接修改讀取的檔案內容,而不是由螢幕輸出
動作說明:[n1,[n2]] function
n1,n2不見得會存在,一般代表選擇進行動作的行數
function參數:
a :新增,a的後面可以接字串,而這些字串會在目前的下一行出現
i :插入,i 的後面可以接字串,而這些字串會在目前的上一行出現
c :替換,c的後面可以接字串,這些字串可以替換n1,n2之間的行
s :替換,可以直接進行替換工作,通常這個s可以搭配Regex
d :刪除,因為是刪除,所以d後面通常不接任何參數
p :列印,也就是將某個選擇的資料列印出來,通常p會與參數sed -n一起運行
12.3擴充的Regex
+ :重複一個或多個的前一個RE字元
? :0個或一個的前一個RE字元
| :用或的方式找出字串
() :找出“組”的字串 (如:egrep -n ‘g(la|oo)d’ regular_express.txt 表示找出glad或good字串)
()+:多個重複的群組的判別 (如echo 'AxyzxyzxyzxyzC' | egrep 'A(xyz)+C' 找出開頭是A結尾是C,中間有一個以上的“xyz”字串)
12.4檔案的格式化與相關處理
格式化列印 printf:
格式:printf '列印格式' 實際內容
格式方面的幾個特殊樣式:
\a 警告聲音輸出
\b 退格鍵
\f 清除螢幕
\n 輸出新的一行
\r 亦即Enter按鍵
\t 水平的tab按鍵
\v 垂直的tab按鍵
\xNN NN為兩個數字,可以轉換數字成字元
關於C語言內,常見的變數格式
%ns :n代表數字,s代表string,即多個字元
%ni : n代表數字,i代表interger,即多少整數字數
%N.nf :n和N都是數字,f代表float,如十個位元,小數點兩位為 %10.2f
awk工具 (詳見sed & awk):
格式:awk ‘條件類型1{動作1} 條件類型2{動作2} ...’ filename
awk主要是處理每一行的欄位內的資料,而預設的欄位的分割符為空白格鍵或tab鍵
變數:
NF : 每一行($0)擁有的欄位總數
NR :目前awk所處理的是“第幾行”資料
FS :目前的分隔字元,預設是空格鍵
邏輯運算子:
> < >= <= == !=
例:
cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "\t" $3}'
cat pay.txt | awk '{if(NR==1) printf "%10s %10s,%10s\n",$1,$4,"Total"} NR>=2 {total=$1+$4 printf "%10s %10d %10.2f\n",$1,$3,total}'
文本比較工具diff:
diff用於比較兩個檔案之間的區別,並且是以行為單位的,diff也可以比較兩個目錄
格式:diff [-bBi] from-file to-file
-b :忽略一行當中僅有多個空白的區別(如“about me”和“about me”視為相同)
-B:忽略空白行的區別
-i:忽略大小寫區別
patch -pN <patch_file 更新
patch -R -pN <patch_file 還原
範例:以/tmp/test內的passwd.old 與passwd.new 製作補丁檔案,並更新舊版資料
diff -Naur passwd.old passwd.new >passwd.patch
更新舊檔案,變成和新檔案一樣
patch -p0 <passwd.patch
(pathing file passwd.old)
恢複舊檔案的內容
patch -R -p0 <passwd.patch
檔案列印pr:
pr /etc/man.config (列印文字檔man.config)
鳥哥的linux私房菜 Regex 有個例子似乎結果不正確
一:
grep -nv '^$' /etc/syslog.conf
-v ‘^$' 這個是顯示除了空行之外的所有行。-n 是每行顯示行號。 你如果不想顯示行號,不要n參數就行。
如:
grep -v '^$' /etc/syslog.conf
二:
同樣道理,這個是顯示除了帶頭是#的其他所有行。 但你因為之前用了n,多了個行號,所以帶頭的已經不是#號,而是數字,所以沒用。還是去掉n的參數。
grep -v '^#'
鳥哥的linux私房菜第7章課後練習題
find /etc -size +50k -a ! -user root -exec ls -ld {} \;
find /etc -size +50k -a ! -user root -type f -exec ls -l {} \;
上面兩式均可!注意到 ! ,那個 ! 代表的是反向選擇,亦即『不是後面的項目』之意!
find /etc -size +1500k -o -size 0
相對於 -a ,那個 -o 就是或 (or) 的意思!
參考資料:linux.vbird.org/