正則表達式
簡單而言,正則表達式通過一些特殊符號的幫助,使用戶可以輕鬆快捷的完成查找、刪除、替換等處理程序。
正則表達式特殊符號
一些特殊符號的表示
[:alnum:]代表英文大小寫字母及數字
[:alpha:]代表英文大小寫字母
[:blank:]代表空格和 tab 鍵
[:cntrl:]鍵盤上的控制按鍵,如 CR,LF,TAB,DEL
[:digit:]代表數字
[:graph:]代表空白字符以外的其他
[:lower:]小寫字母
[:print:]可以被打印出來的任何字符
[:punct:]代表標點符號
[:upper:]代表大寫字符
[:space:]任何會產生空白的字符如空格,tab,CR 等
[:xdigit:]代表16進制的數字類型
grep查找
grep命令可以使用正則表達式搜索文本,並把匹配的行打印出來,其常用方法如下:
grep [-acinv] [--color=auto] '搜尋字符串' filename
選項與參數:
-a :將 binary 文件以 text 文件的方式搜尋數據
-c :計算找到 '搜尋字符串' 的次數
-i :忽略大小寫的不同,所以大小寫視爲相同
-n :順便輸出行號
-v :反向選擇,亦即顯示出沒有 '搜尋字符串' 內容的那一行!
--color=auto :可以將找到的關鍵詞部分加上顏色的顯示
case1
查找特定的字符串
grep -n 'the' regular_express.txt # 查找'the' 字符串
case2
字符組匹配,[]中包含的任意一個字符,只能是一個,字符組支持"-"連字符來表示一個範圍,[^ ...]
是排除型字符組,用來排除後面的字符
[abc] :表示“a”或“b”或“c”
[0-9] :表示 0~9 中任意一個數字,等價於[0123456789]
[\u4e00-\u9fa5] :表示任意一個漢字
[^a1<] :表示除“a”、“1”、“<”外的其它任意一個字符
[^a-z] :表示除小寫字母外的任意一個字符
grep -n 't[ae]st' regular_express.txt # 查找“tast”或者“test”兩個字符串
grep -n '[^#]' regular_express.txt #查找不包含“#”的字符串
grep -n '[^g]oog' regular_express.txt # 查找"oog",但是不查找"goog"
grep -n '[^go]oog'regular_express.txt# 查找"oog",但是不查找"goog"和"ooog"
grep -n '[[:lower:]]' regular_express.txt # 查找小寫字母
case3
行首符^,行尾符$,具體應用如下
grep -n '^the' regular_express.txt # 查找行首爲"the"的所有行
grep -n '^[A-Z]' regular_express.txt # 查找行首爲大寫字母的所有行
grep -n '[^A-Z]' regular_express.txt # 查找除了大寫字母以外的所有字符,注意和上面區分
grep -n 'd$' regular_express.txt # 查找以"d"結尾的所有行
grep -n '^$' regular_express.txt # 查找空行
case4
grep的反向選擇和管道線聯合應用
grep -v '^$' /etc/insserv.conf | grep -v '^#' # 先過濾掉空白行,然後過濾掉註釋行(以#開頭)
case5
小數點".“表示任意一個字符,星號”*"表示重複的字符
grep -n 'a.ou.' regular_express.txt # 查找a?ou?類型的字符
*(星號):代表重複前面0個或者多個字符。
e*: 表示具有空字符或者一個以上e字符。
ee*,表示前面的第一個e字符必須存在。第二個e則可以是0個或者多個e字符。
eee*,表示前面兩個e字符必須存在。第三個e則可以是0個或者多個e字符。
ee*e :表示前面的第一個與第三個e字符必須存在。第二個e則可以是0個或者多個e字符。
case6
大括號{}可以限定一個範圍區間重複的字符數,注意,必須用轉義字符來表示這個大括號,即爲\{\}
,否則出錯。
grep -n 'o\{2\}' regular_express.txt # 查找連續的兩個"o"
grep -n 'go\{2,5\}g' regular_express.txt # 查找g後面接2到5個o,然後再接g的字符串
小結
^word 表示帶搜尋的字符串(word)在行首
word$ 表示帶搜尋的字符串(word)在行尾
.(小數點) 表示1個任意字符
\ 表示轉義字符,在特殊字符前加\會將特殊字符意義去除
* 表示重複0到無窮多個前一個RE(正則表達式)字符
[list] 表示搜索含有l,i,s,t任意字符的字符串
[n1-n2] 表示搜索指定的字符串範圍,例如[0-9] [a-z] [A-Z]等
[^list] 表示反向字符串的範圍,例如[^0-9]表示非數字字符,[^A-Z]表示非大寫字符範圍
\{n,m\} 表示找出n到m個前一個RE字符
\{n,\} 表示n個以上的前一個RE字符
sed編輯器
sed 是非交互式的編輯器。它不會修改文件,除非使用 shell 重定向來保存結果。默認情況下,所有的輸出行都被打印到屏幕上。sed 編輯器逐行處理文件(或輸入),並將結果發送到屏幕。其常用方法如下:
sed [-nefri] ‘command’ 輸入文本
常用選項:
-n:使用安靜(silent)模式。如果加上 -n 參數後,則只有經過sed 特殊處理的那一行(或者動作)纔會被列出來。
-e:直接在指令列模式上進行 sed 的動作編輯;
-f:直接將 sed 的動作寫在一個檔案內,-f filename則可以執行 filename 內的sed 動作;
-r:sed的動作支援的是延伸型正規表示法的語法。(預設是基礎正規表示法語法)
-i:直接修改讀取的檔案內容,而不是由屏幕輸出。
常用命令:
a:新增,a的後面可以接字串,而這些字串會在當前行的下一行
c:取代,c的後面可以接字串,這些字串可以取代 n1,n2 之間的行
d:刪除,因爲是刪除,所以d後面通常不接任何內容
i:插入,i的後面可以接字符串,而這些字符串會在新的一行出現(目前的上一行)
p:打印,將某個選擇的部分打印出。通常p會與參數sed -n一起運作(僅打印需要的行)
s:替換,可以直接進行替換的工作,通常s動作可以搭配正規表示法
case1
nl regular_express.txt | sed '2,5d' # 將 regular_express.txt 的內容列出並打印行號,同時,將2-5 行刪除顯示
nl regular_express.txt | sed '2d' # 同上,僅刪除第二行
nl regular_express.txt | sed '3,$d' #同上,刪除第3行到最後一行
sed -i '1d' regular_express.txt # 在原文件中刪除第 1 行
case2
a表示在行後加上字符串,i表示在行前添加字符串
nl regular_express.txt | sed '2a test' # 在第二行後添加 test 字符串
nl regular_express.txt | sed '2i test' # 在第二行前添加 test 字符串
nl regular_express.txt | sed '2a test\ntest' # 在第二行後加入兩行 test,“\n”表示換行符
case3
c 爲替換內容選項
nl regular_express.txt | sed '2,5c No 2-5 number' # 將 2-5 行內容取代爲"No 2-5 number"
case4
sed ‘s/被替換字符串/新字符串/g’
/sbin/ifconfig eth0 |grep 'inet ' # 在/sbin/ifconfig eth0 的結果中查找‘inet’,打印至終端
# 結果是inet addr:192.168.40.12 Bcast:0.0.0.0 Mask:255.255.255.0
/sbin/ifconfig eth0 |grep 'inet '| sed 's/inet ....://g' # 將IP地址前的字符去掉
/sbin/ifconfig eth0 |grep 'inet '| sed 's/.\{0,9\}://' # 功能和前面一樣,去掉:前的若干個字符,最多9個
/sbin/ifconfig eth0 |grep 'inet '| sed 's/.inet...://g'| sed 's/.....:.*$//g' # 將IP地址後的部分也去掉,.*表示無限個任意字符
awk文本分析
awk是一個強大的文本分析工具,把文件逐行的讀入,以空格爲默認分隔符將每行切片,切開的部分再進行各種分析處理。
使用方法
awk '{pattern + action}' {filenames}
其中 pattern 表示 AWK 在數據中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令。花括號{}不需要在程序中始終出現,但它們用於根據特定的模式對一系列指令進行分組。 pattern就是要表示的正則表達式,用兩個斜槓/括起來。
case1
last -n 5 # 取出登錄數據前5行
# 結果如下
root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in
root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41)
root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48)
dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00)
root tty1 Fri Sep 5 14:09 - 14:10 (00:01)
last -n 5 | awk '{print $1}' # 顯示最近登錄的5個帳號,$1代表用空格或TAB隔開的第一個字段,以此類推,此句表示取每一行的第一個字段
# 結果如下
root
root
root
dmtsai
root
case2
cat /etc/passwd |awk -F ':' '{print $1}' # 功能類似,使用了-F ':'指定分隔符爲冒號
# 結果如下
root
daemon
bin
sys
cat /etc/passwd |awk -F ':' '{print $1"\t"$7}' # 顯示/etc/passwd的賬戶和賬戶對應的shell,而賬戶與shell之間以tab鍵分割
# 結果如下
root /bin/bash
daemon /bin/sh
bin /bin/sh
sys /bin/sh
case3
awk -F: '/root/' /etc/passwd # 搜索/etc/passwd有root關鍵字的所有行
# 結果如下
root:x:0:0:root:/root:/bin/bash
這種是pattern的使用示例,匹配了pattern(這裏是root)的行纔會執行action(沒有指定action,默認輸出每行的內容)。
搜索支持正則,例如找root開頭的: awk -F: ‘/^root/’ /etc/passwd
awk -F: '/root/{print $7}' /etc/passwd # 搜索/etc/passwd有root關鍵字的所有行,並顯示對應的shell
# 結果如下
/bin/bash
這裏指定了action{print $7}
awk內置變量
awk有許多內置變量用來設置環境信息,這些變量可以被改變,下面給出了最常用的一些變量。
ARGC 命令行參數個數
ARGV 命令行參數排列
ENVIRON 支持隊列中系統環境變量的使用
FILENAME awk瀏覽的文件名
FNR 瀏覽文件的記錄數
FS 設置輸入域分隔符,等價於命令行 -F選項
NF 瀏覽記錄的域的個數(每一行字段個數)
NR 已讀的記錄數(行號)
OFS 輸出域分隔符
ORS 輸出記錄分隔符
RS 控制記錄分隔符
舉一個例子
# 統計/etc/passwd:文件名,每行的行號,每行的列數,對應的完整行內容($0是代指整行)
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
擴展規則
egrep
正規表達方法
grep -v '^$' regular_express.txt |grep -v '^#' # 先去除空行,再去除註釋行
需要用到管道線,grep搜尋了兩次,如果使用延伸型的正則表達式,則可以簡化爲
egrep -v '^$|^#' regular_express.txt # 相當於或操作
grep 默認僅支持基礎正則表達式,如果要使用擴展性正則表達式,可以使用 grep - E。grep -E 與 egrep 相當於命令別名關係。
常用擴展規則
加號+表示重複一個或一個以上的前一個 RE 字符
egrep -n 'go+d' regular_express.txt # gd之間,o至少重複兩次
grep -n 'goo*d' regular_express.txt # 普通寫法
問號?表示重複重複零個或一個前一個RE字符
egrep -n 'go?d' regular_express.txt # 僅搜索good或god
分隔符|表示用或的方式找出數個字符串
egrep -n 'gd|good' regular_express.txt
括號()表示找出羣組字符串
egrep -n 'g(la|oo)d' regular_express.txt # 搜索good或glad
括號加號{}+表示多個重複羣組判別
# 找開頭是A結尾是C,中間有一個以上的 ‘xyz’ 或 ‘xz’ 字符串
echo 'AxyzxyzxyzxyzC'|egrep 'A(xyz)+C' # 可以匹配
echo 'AxyzxyzxyzxyzC'|egrep 'A(xz)+C' # 無法匹配