grep全面搜索正則表達式並把行打印出來,是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。它的輸出通常是打印在屏幕上。python
Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不一樣。egrep是grep的擴展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它們把全部的字母都看做單詞,也就是說,正則表達式中的元字符表示回其自身的字面意義,再也不特殊。linux使用GNU版本的grep。它功能更強,能夠經過-G、-E、-F命令行選項來使用egrep和fgrep的功能。linux
grep 命令在一個或多個文件中查找某個字符模式。若是這個模式中包含空格,就必須用引號把它括起來。 grep 命令中,模式能夠是一個被引號括括起來的字符串,也能夠是單個詞,位於模式以後全部的單詞都被視爲文件名。 grep 將輸出發送到屏幕,它不會對輸入文件進行任何修改或變化。
示例1:grep root /etc/passwd
說明:grep命令將在文件/etc/passwd中查找模式root。若是查找成功,文件中相應的行就會顯示在屏幕上,返回狀態爲0。若是查找失敗,就不會有任何輸出,返回狀態爲1。若是文件不存在,屏幕會顯示報錯信息,返回狀態爲2。正則表達式
$ grep root /etc/passwd123 # 文件不存在 grep: /etc/passwd123: 沒有那個文件或目錄 $ echo $? 2 # 狀態值爲2 $ grep lala /etc/passwd # 查找模式不匹配 $ echo $? 1 # 狀態值爲1 $ grep root /etc/passwd # 成功匹配 root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin $ echo $? 0 # 狀態值爲0,成功匹配
grep命令的輸入能夠來自文件,也能夠來自標準輸入或者管道。
示例2:ps aux | grep docker
docker
[root@moli-04 ~]# ps aux | grep docker root 893 0.1 5.5 486428 55472 ? Ssl 11:33 0:02 /usr/bin/dockerd root 986 0.0 2.9 384508 29544 ? Ssl 11:33 0:01 docker-containerd --config /var/run/docker/containerd/containerd.toml root 1296 0.0 0.2 108964 2628 ? Sl 11:33 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.17.0.2 -container-port 5000 root 1301 0.0 0.2 7488 2676 ? Sl 11:33 0:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/63683775af1b8dd27080dbf898619a3f50a17bf557ac0e133ab52310c84dbf5e -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc root 1317 0.0 0.8 20272 8128 ? Ssl 11:33 0:00 registry serve /etc/docker/registry/config.yml root 1404 0.0 0.0 112720 968 pts/0 R+ 12:00 0:00 grep --color=auto docker
ps aux
命令的輸入被送到grep,而後包含docker
的行都被輸出到屏幕上。shell
grep支持不少正則表達式元字符,以便用戶更精確地定義查找模式。
下面列出grep支持的經常使用基本表達式:bash
字符 | 含義 |
---|---|
a | 匹配字母a |
. | 匹配任意一個字符 |
* | 匹配前一個字符出現0次或屢次 |
.* | 匹配任意字符 |
[ ] | 匹配集合中任意一個字符,括號中爲一個集合 |
[x-y] | 匹配連續的字符串範圍 |
^ | 匹配字符的開頭 |
$ | 匹配字符的結尾 |
[^] | 匹配否點,對括號中的集合取反 |
\ | 匹配轉義後的字符串 |
\{n,m\} | 匹配前一個字符出現n到m次 |
\{n,\} | 匹配前一個字符至少出現n次 |
\{n\} | 匹配前一個字符出現n次 |
() | 保存已匹配的字符串,最大存儲9個,括號左右須要使用轉義字符(這裏不知道爲何顯示不了...) |
選項 | 說明 |
---|---|
-A num | (A即after)顯示匹配的行,並顯示匹配行的後num行,num爲數字 |
-B num | (B即before)除了顯示匹配的行,還顯示匹配行的前num行,num爲數字 |
-C num | 先後匹配(至關於-A和-B)除了顯示匹配的行,還顯示匹配行的先後num行 |
-n | 在輸出結果顯示行號,行號是該行在原來文件裏的行號,而不是輸出結果的行號 |
-v | 取反,輸出與匹配模式相反的內容 |
-E | 至關與egrep,後面的模式是擴展正則表達式(grep -E == egrep) |
-o | 只顯示匹配內容,grep默認輸出匹配內容的行,加上-o選項只輸出匹配的模式 |
-d | 當指定要查找的是目錄而非文件時,必須使用這項參數,不然grep指令將回報信息並中止動做。 |
-c | count統計,統計匹配結果的行數,有n行匹配就輸出數字n |
實例:
將/etc/passwd的前10行輸出保存到/tmp/grep.txt,下面grep實例都用這個文本文件。markdown
[root@moli-04 ~]$ head -n 10 /etc/passwd > /tmp/grep.txt [root@moli-04 ~]$ cat /!$ cat //tmp/grep.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin
示例1:查找特定字符串,顯示行號ssh
[root@moli-04 ~]$ grep -n "root" /tmp/grep.txt 1:root:x:0:0:root:/root:/bin/bash 10:operator:x:11:0:operator:/root:/sbin/nologin
示例2:取反,將不包含root的行輸出,並顯示行號tcp
[root@moli-04 ~]$ grep -nv "root" /tmp/grep.txt 2:bin:x:1:1:bin:/bin:/sbin/nologin 3:daemon:x:2:2:daemon:/sbin:/sbin/nologin 4:adm:x:3:4:adm:/var/adm:/sbin/nologin 5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6:sync:x:5:0:sync:/sbin:/bin/sync 7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8:halt:x:7:0:halt:/sbin:/sbin/halt 9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
示例3:-A,-B,-C的使用編輯器
[root@moli-04 ~]$ grep -A 1 root /tmp/grep.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin -- operator:x:11:0:operator:/root:/sbin/nologin [root@moli-04 ~]$ grep -B 1 root /tmp/grep.txt root:x:0:0:root:/root:/bin/bash -- mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin [root@moli-04 ~]$ grep -C 1 root /tmp/grep.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin -- mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin
第一條命令輸出包含root的行,並輸出它的後一行。
第二條命令輸出包含root的行,並輸出它的前一行。
第三條命令輸出包含rott的行,並輸出它的先後一行。
示例4:-c統計行數,包含root的行有幾行
[root@moli-04 ~]$ grep -c root /tmp/grep.txt 2
示例5:^,$的使用
# 匹配以r字母爲開頭的行 [root@moli-04 ~]$ grep ^r /tmp/grep.txt root:x:0:0:root:/root:/bin/bash [root@moli-04 ~]# # 匹配以nologin單詞爲結尾的行 [root@moli-04 ~]$ grep nologin$ /tmp/grep.txt bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin
示例6:[]的使用
# 查找包含ost或者oot的行 [root@moli-04 ~]$ grep o[os]t /tmp/grep.txt root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
示例7:匹配包含數字和包含小寫字母的行'[0-9]'和'[a-z]'
$ grep '[0-9]' /tmp/grep.txt $ grep '[a-z]' /tmp/grep.txt
輸出結果太長就不復制進來了,多多動手實踐吧(=゚ω゚)。
示例8:正則表達式實踐
test.txt文件內容以下,注意有空白行。
aaa bbb 111 222 AAA BBB hell world I love python pppppython
匹配數字開頭的行:
$ grep '^[0-9]' test.txt 111 222
匹配小寫字母開頭的行:
$ grep '^[a-z]' test.txt aaa bbb hell world pppppython
匹配空白行,這裏-n顯示行號顯示空白行在第幾行
$ grep -n '^$' test.txt 7:
邏輯匹配或者‘|’,須要使用轉義字符''
$ grep '111\|222' test.txt # 匹配111或者222 111 222
而且,利用管道
$ grep 'love' test.txt | grep 'python' # 匹配帶有love和python的行 I love python
匹配p字母出現至少4次
$ grep 'p\{4,\}' test.txt # 中括號左右須要使用轉義字符\ pppppython
egrep 在 grep 的基礎上增長了更多的元字符。可是 egrep 不容許使用(),\{\}.下面是egrep支持使用的正則表達式元字符(只列舉新增的)。
字符 | 說明 |
---|---|
+ | 匹配一個或多個前面的字符,至少一個 |
? | 匹配0個或1個起那麼的字符,只能0或者1 |
豎線 | 或者(這裏豎線就用中文了,由於markdown表格的豎線轉義不了...) |
() | 匹配正則集合 |
sed經過文件或者管道讀取文件內容,但sed默認並不直接修改源文件,而是將讀入的內容複製到緩衝區中,咱們稱之爲模式空間,全部的指令操做都是在模式空間中進行的,而後sed根據對應的指令對模式空間內的內容進行處理並輸出結果,默認輸出至標準輸出(屏幕)。
用法: sed [選項] {腳本指令} [輸入文件]
sed操做地址匹配
sed 命令在沒有給定的位置時,默認會處理全部行;
sed支持下面幾種地址類型;
示例 | 說明 |
---|---|
number | 指定輸入文件的惟一行號 |
first~step | 指定first開始,並指定操做步長爲step。好比1~2,指定第一行、第三行、第五行...爲操做地址。 |
$ | 匹配文件最後一行 |
/regexp/ | 經過正則表達式匹配操做地址,//中間是正則表達式 |
addr1.addr2 | 匹配從操做地址1到操做地址2的全部行 |
addr1,+N | 匹配地址1以及後面的N行內容 |
sed經常使用選項
選項 | 說明 |
---|---|
-n | 靜默輸出,sed程序默認在全部腳本指令執行完畢後自動打印模式空間中的內容,該選項能夠屏蔽自動打印 |
-e | 容許多個腳本指令被執行,指令順序會影響結果 |
-i | 修改源文件的內容,慎用 |
-f | 從文件中讀取腳本指令,對編寫自動腳本程序很實用 |
-r | 讓sef支持擴展正則表示式 |
sed經常使用指令
指令 | 說明 |
---|---|
a | 追加(在原先行後追加) |
d | 刪除 |
c | 更改 |
i | 插入(在原先行前插入) |
s | 替換 |
l | 打印(顯示非打印字符) |
L | 打印(不顯示非打印字符) |
p | 打印 |
w | 保存至文件 |
部分指令詳解
替換指令:s
使用格式:[address]s/pattern/replacement/flags
address是操做地址,s爲替換指令,pattern須要替換的內容,replacement替換的新內容,flags標記。
flags有幾種:
s/hello/world/2
s/a/b/g
sed.txt文件內容
$ cat sed.txt ONBOOT=yes IPADDR=192.168.30.6 NETMASK=255.255.255.0 GATEWAY=192.168.30.2 DNS=119.29.29.29
在第一行後面追加TYPE=Ethernet
$ sed '1a TYPE=Ethernet' sed.txt ONBOOT=yes TYPE=Ethernet #追加項 IPADDR=192.168.30.6 NETMASK=255.255.255.0 GATEWAY=192.168.30.2 DNS=119.29.29.29
在第2行前面插入TYPE=Ethernet
$ sed '2i TYPE=Ethernet' sed.txt ONBOOT=yes TYPE=Ethernet # 插入項 IPADDR=192.168.30.6 NETMASK=255.255.255.0 GATEWAY=192.168.30.2 DNS=119.29.29.29
全局替換yes爲no
$ sed 's/yes/no/g' sed.txt ONBOOT=no # yes被替換爲no IPADDR=192.168.30.6 NETMASK=255.255.255.0 GATEWAY=192.168.30.2 DNS=119.29.29.29
刪除第1,2行的內容
$ sed '1,2d' sed.txt # 1,2行沒了 NETMASK=255.255.255.0 GATEWAY=192.168.30.2 DNS=119.29.29.29
匹配以DNS爲開頭的行,並在該行前插入DEVICE=ens33
$ sed '/^DNS/i DEVICE=ens33' sed.txt ONBOOT=yes IPADDR=192.168.30.6 NETMASK=255.255.255.0 GATEWAY=192.168.30.2 DEVICE=ens33 # 插入的行,下一行是以DNS爲開頭 DNS=119.29.29.29
除了直接將操做指令寫在命令行裏,還能夠將操做指令寫在腳本里,而後使用sed -f
讀取指令。
建立腳本,內容以下
$ cat sed.sh # 這個腳本的做用是打印文件的奇數行,須要配合-n選項使用 1~2p
-f讀取指令
$ sed -f sed.sh -n sed.txt ONBOOT=yes NETMASK=255.255.255.0 DNS=119.29.29.29
當須要執行多個指令的時候,能夠有幾種方式。
$ sed -n 's/yes/no/;s/static/dhcp/p' sed.txt #使用分號 $ sed -e 's/yes/no/' -e 's/static/dhcp/' sed.txt # 使用-e選項 $ sed ' >s/yes/no/ >s/static/dhcp/' sed.txt
常見案例1:使用sed命令將文件帶#的行刪除
實際在修改配置文件的時候,配置文件帶有大量的註釋,一般以'#'爲開頭,因而能夠將這些以#爲開頭的行刪掉。
[root@moli-04 tmp]$ cat sed2.txt #ajksshdja jskdjks #kjklasj 123 $ sed -i '/^#/d' sed2.txt [root@moli-04 tmp]$ cat sed2.txt jskdjks 123
常見案例2:刪除空白行與刪除以數字開頭的行
$ sed '/^$/d' sed.txt $ sed '/^[0-9]*/d' sed.txt
常見案例3:查找網卡對應ip地址
$ ifconfig | grep -A1 ens33|grep inet|sed s/^.*inet//g | sed 's/netmask.*$//g' 192.168.30.6