Linux命令行正則表達式基礎

正則表達式

簡單而言,正則表達式通過一些特殊符號的幫助,使用戶可以輕鬆快捷的完成查找、刪除、替換等處理程序。

正則表達式特殊符號

一些特殊符號的表示

[: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' # 無法匹配
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章