標籤:style blog color os 使用 io 檔案 for 資料
【著作權聲明:轉載請保留出處:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】
Linux系統中有很多檔案,比如設定檔、記錄檔、使用者檔案等。檔案中都包含了大量的資訊,我們可以使用cat等命令輕鬆將其輸出到螢幕,但如果要從檔案中分析或提取資料,還需要其他工具來實現。而linux正好提供了這些工具:grep、awk、sed等。把這些工具使用好,可以極大地提高你的工作效率,對系統管理員分析資料有極大協助,而對linux開發人員來說也可以在開發測試中以及平時使用中節省不少時間。本系列文中將介紹這些工具來實現文本過濾分析。
常用的grep選項有:
-c 只輸出匹配行的計數。
-i 不區分大小寫(只適用於單字元) 。
-h 查詢多檔案時不顯示檔案名稱。
-l 查詢多檔案時只輸出包含匹配字元的檔案名稱。
-n 顯示匹配行及行號。
-s 不顯示不存在或無匹配文本的錯誤資訊。
-v 顯示不包含匹配文本的所有行。
本節文章大數樣本均使用檔案/etc/passwd來作為過濾對象。
一、匹配行
最簡單(也是最常用)的用法是在一個檔案(或多個檔案)中尋找某一字串,比如在檔案/etc/passwd中尋找包含字串”user”的行:
# grep "user" /etc/passwdusbmuxd:x:113:113:usbmuxd user:/:/sbin/nologinoprofile:x:16:16:Special user account to be used by OProfile:/var/lib/oprofile:/sbin/nologinqemu:x:107:107:qemu user:/:/sbin/nologinradvd:x:75:75:radvd user:/:/sbin/nologintss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologinsaslauth:x:994:76:"Saslauthd user":/run/saslauthd:/sbin/nologinrpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologinnm-openconnect:x:992:991:NetworkManager user for OpenConnect:/:/sbin/nologin#
一般我們將要尋找的字串用雙引號包含起來,一是以防被誤解為 s h e l l命令,二是可以用來尋找多個單片語成的字串。
使用-c選項輸出匹配行數:
# grep -c "user" /etc/passwd8#
使用-n選項輸出匹配行及行號:
# grep -n "user" /etc/passwd18:usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin19:oprofile:x:16:16:Special user account to be used by OProfile:/var/lib/oprofile:/sbin/nologin22:qemu:x:107:107:qemu user:/:/sbin/nologin25:radvd:x:75:75:radvd user:/:/sbin/nologin27:tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin30:saslauth:x:994:76:"Saslauthd user":/run/saslauthd:/sbin/nologin34:rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin38:nm-openconnect:x:992:991:NetworkManager user for OpenConnect:/:/sbin/nologin#
其中第一列輸出行號,後面輸出行內容。
我們發現上面匹配“user”的行有的返回的是包含“rpcuser”和“trousers“的行,如果我們要精確地抽取“user”的行,可以這樣用:
# grep -n "\<user\>" /etc/passwd18:usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin19:oprofile:x:16:16:Special user account to be used by OProfile:/var/lib/oprofile:/sbin/nologin22:qemu:x:107:107:qemu user:/:/sbin/nologin25:radvd:x:75:75:radvd user:/:/sbin/nologin30:saslauth:x:994:76:"Saslauthd user":/run/saslauthd:/sbin/nologin38:nm-openconnect:x:992:991:NetworkManager user for OpenConnect:/:/sbin/nologin#
瞬間少了27和34行。
如果要忽略大小寫話可以使用-i選項,如下:
[[email protected] shell_text_filter]# grep -ni "\<user\>" /etc/passwd12:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin17:polkitd:x:999:999:User for polkitd:/:/sbin/nologin18:usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin19:oprofile:x:16:16:Special user account to be used by OProfile:/var/lib/oprofile:/sbin/nologin20:colord:x:998:998:User for colord:/var/lib/colord:/sbin/nologin22:qemu:x:107:107:qemu user:/:/sbin/nologin25:radvd:x:75:75:radvd user:/:/sbin/nologin30:saslauth:x:994:76:"Saslauthd user":/run/saslauthd:/sbin/nologin34:rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin35:nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin38:nm-openconnect:x:992:991:NetworkManager user for OpenConnect:/:/sbin/nologin
瞬間多了幾行。
使用選項-v可以過濾不含指定字串的行:
# grep -v "a" /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologinsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownnobody:x:99:99:Nobody:/:/sbin/nologinpolkitd:x:999:999:User for polkitd:/:/sbin/nologinusbmuxd:x:113:113:usbmuxd user:/:/sbin/nologinunbound:x:997:997:Unbound DNS resolver:/etc/unbound:/sbin/nologinqemu:x:107:107:qemu user:/:/sbin/nologinopenvpn:x:996:995:OpenVPN:/etc/openvpn:/sbin/nologintcpdump:x:72:72::/:/sbin/nologin#
上面列出的行都不包含”a”。
結合使用ps命令可以尋找當前系統是否正在運行我們需要的程式,命令如下:
# ps x | grep vsftpd1020 ? Ss 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf10264 pts/1 S+ 0:00 grep --color=auto vsftpd#
但是發現列印結果包含當前shell進程,我們可以通過使用-v選項來過濾輸出結果,如下:
# ps x | grep "vsftpd" | grep -v "grep"1020 ? Ss 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf#
該方法相當常用。
二、結合使用Regex
其實grep過濾可以和Regex聯合起來用,使匹配加入一些規則,這樣的使用更為靈活。使用Regex時最好用單引號括起來,這樣可以防止 g r e p中使用的專有模式與一些shell命令的特殊方式相混淆。
這裡我們先講一下Regex,下面是Regex基本元字元集及其含義:
^ 只只匹配行首
$ 只只匹配行尾
* 只一個單字元後緊跟*,匹配0個或多個此單字元
[ ] 只匹配[ ] 內字元。可以是一個單字元,也可以是字元序列。可以使用 -表示[ ]內字元序列範圍,如用 [ 1 - 5 ]代替[ 1 2 3 4 5 ]
\ 只用來屏蔽一個元字元的特殊含義。因為有時在 s h e l l中一些元字元有
特殊含義。\可以使其失去應有意義
. 只匹配任意單字元
p a t t e r n \ { n \ } 只用來匹配前面 p a t t e r n出現次數。n為次數
p a t t e r n \ { n,\ } m 只含義同上,但次數最少為 n
p a t t e r n \ { n,m \ } 只含義同上,但 p a t t e r n出現次數在n與m之間。
句點“.”可以匹配任意單字元。“.”允許匹配A S C I I集中任一字元,或為字母,或為數字。
比如:
# grep '.mm..' /etc/passwdsmmsp:x:51:51::/var/spool/mqueue:/sbin/nologin## grep 'm..l' /etc/passwdmail:x:8:12:mail:/var/spool/mail:/sbin/nologinmailnull:x:47:47::/var/spool/mqueue:/sbin/nologin#
在行首以^匹配字串或字元序列,^只允許在一行的開始匹配字元或單詞。
比如匹配以ma開頭的行:
# grep '^ma' /etc/passwd mail:x:8:12:mail:/var/spool/mail:/sbin/nologinmailnull:x:47:47::/var/spool/mqueue:/sbin/nologin#
Regex可以將各種模式混合使用:
# grep '^ma....ll' /etc/passwdmailnull:x:47:47::/var/spool/mqueue:/sbin/nologin#
^在Regex中使用頻繁,因為大量的抽取操作通常在行首。
在行尾以$匹配字串或字元, $與^正相反,它在行尾匹配字串或字元, $符號放在匹配單詞後。比如匹配以bash結尾的行:
# grep 'bash$' /etc/passwdroot:x:0:0:root:/root:/bin/bashallen:x:1000:1000:allen:/home/allen:/bin/bashaln:x:1001:1001::/home/aln:/bin/bash#
如果要匹配所有空行,執行以下操作:
^ $
具體分析為匹配行首,又匹配行尾,中間沒有任何模式,因此為空白行。
如果只返回包含一個字元的行,操作如下:
^ . $
不像空白行,在行首與行尾之間有一個模式,代表任意單字元。
使用*匹配字串中的單字元或其重複序列,使用此特殊字元匹配任一字元或字串的重複多次運算式。
使用[]匹配一個範圍或集合,可以用逗號將括弧內要匹配的不同字串分開,使用“ - ”表示一個字串範圍,表明字串範圍從“ -”左邊字元開始,到“ - ”右邊字元結束。
比如要匹配包含aln或all的行,可以如下寫:
# grep 'al[l,n]' /etc/passwdallen:x:1000:1000:allen:/home/allen:/bin/bashaln:x:1001:1001::/home/aln:/bin/bash#
忽略大小寫也可以由另外一種方式:
# grep 'System' /etc/passwddbus:x:81:81:System message bus:/:/sbin/nologinpulse:x:995:994:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin[[email protected] shell_text_filter]# grep '[Ss]ystem' /etc/passwddbus:x:81:81:System message bus:/:/sbin/nologinsystemd-journal-gateway:x:191:191:Journal Gateway:/var/log/journal:/usr/sbin/nologinpulse:x:995:994:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin#
使用\{\}匹配模式結果出現的次數,使用*可匹配所有匹配結果任意次,但如果只要指定次數,就應使用 \ { \ } ,此模式有三種形式,即:
pattern\{n\} 匹配模式出現n次。
pattern\{n,\} 匹配模式出現最少 n次。
pattern\{n,m} 匹配模式出現n到m次之間,n , m為0 - 2 5 5中任意整數。
過濾字元m至少出現2次的行:
# grep 'm\{2,\}' /etc/passwdsmmsp:x:51:51::/var/spool/mqueue:/sbin/nologin#
過濾9出現2次,並以4結尾的行:
# grep '9\{2,\}4' /etc/passwdpulse:x:995:994:PulseAudio System Daemon:/var/run/pulse:/sbin/nologinsaslauth:x:994:76:"Saslauthd user":/run/saslauthd:/sbin/nologin#
grep命令加-E參數,這一擴充允許使用擴充模式比對。比如要擷取包含allen或aln的行,可以這樣用。
# grep -E 'allen|aln' /etc/passwd allen:x:1000:1000:allen:/home/allen:/bin/bashaln:x:1001:1001::/home/aln:/bin/bash#
shell文本過濾編程(一):grep和Regex