Shell 三劍客之 grep
1. grep 概述
1.1 grep 是什么
在我們?nèi)粘?Linux 運維過程中,最多的就是對 Linux 文件進行處理,grep(global search regular expression (RE) and print out the line)作為一款非常方便且強大的文本搜索工具,其能使用正則表達式搜索文本,并把匹配的行打印出來,其使用對象為 Linux 系統(tǒng)的所有用戶,使得我們?nèi)粘2僮鞲臃奖愫唵巍?/p>
1.2 為什么要用 grep
在 Linux 系統(tǒng)中一切皆文件,我們?nèi)粘5墓ぷ骶褪桥c文件打交道,能夠運用 grep 這款文件搜索工具,可以大大提高我們的工作效率,我們上節(jié)課學習了正則表達式,grep 配合正則表達式能夠作出 1+1 大于 2 的效果,靈活使用使得我們的工作更加高效快捷。
2. grep 詳解
2.1 grep 分類
Unix 的 grep 家族包括 grep、egrep 和 fgrep。egrep 和 fgrep 的命令跟 grep 只有很小不同。
- egrep 是 grep 的擴展,其支持更多 re 元字符,和擴展正則表達式等。
- fgrep 就是 fixed grep 或 fast grep,它們把所有的字母都看作單詞,也就是說,正則表達式中的元字符表示其自身的字面意義,不再特殊。
- linux 使用 GNU 版本的 grep。它功能更強,可以通過 - G、-E、-F 命令行選項來使用 egrep 和 fgrep 的功能。
2.2 grep 工作方式
grep 的工作方式為將一個或多個文件中搜索字符串模版。如果模版包括空格,則必須被引用,模板后的所有字符串被看作文件名。搜索的結(jié)果被送到屏幕,不影響原文件內(nèi)容。
grep 命令結(jié)束后通過一個狀態(tài)值來說明搜索狀態(tài),如果為 0 則意味著搜索成功,反之則為失敗,我們可以利用其對文件自動化處理。
2.3 grep 語法
grep [OPTION]... PATTERN [FILE]
其中 OPTION
有很多方式,例如 - A3 表示顯示符合范本樣式的那一行之外,并顯示該行之后的 3 行內(nèi)容。
PATTERN
表示:匹配的模式,通常為一個表達式。
FilE
為具體的需要處理的問題,當然也可以為標準輸入。
2.3 參數(shù)詳解
在上一節(jié)中我們詳細講解了正則表達式,它就可以用在 grep 命令的 PATTERN
字段中,使得 grep 更加強大,本章節(jié)我們著重來講解 grep 命令的 OPTION
。
不加參數(shù),匹配 /etc/passwd 文件中的 root 行,例如:
[root@master grep]# grep "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
- -A:顯示模式匹配后的幾行
查找 /etc/passwd 文件中以 root 開頭的后兩行,例如:
[root@master grep]# grep -A2 "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
- -B:顯示模式匹配行的前幾行
查找 /etc/passwd 文件中以 bin 開頭的前一行,例如:
[root@master grep]# grep -B1 "^bin" /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
- -C:顯示模式匹配的前后各幾行
查找 /etc/passwd 文件中以 ftp 開頭的前后各 2 行,例如:
[root@master grep]# grep -C2 "^ftp" /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
- -i:忽略大小寫匹配
匹配 /etc/passwd 包含 "Nobody" 的行,例如:
[root@master grep]# grep -i "Nobody" /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
- -o :只顯示匹配到的字符串
匹配出 /etc/passwd 文件中字符串長度最少 10 位的字符 ,例如:
[root@master grep]# grep -o "[[:alnum:]]\{10,\}" /etc/passwd
Management
Kubernetes
- -n:輸出匹配到的行的行號
匹配出 /etc/passwd 文件中包含 root 的字符串的行,例如:
[root@master grep]# grep -n "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
- -v:反向選擇,即顯示除過 匹配’搜尋字符串’ 內(nèi)容的那一行
匹配出 /etc/passwd 中不包含 bash 的行,例如:
[root@master grep]# grep -v "nologin" /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
- -c : 計算找到 ‘搜尋字符串’ 的次數(shù)
計算 /etc/passwd 文件中 root 字符串出現(xiàn)的次數(shù),例如:
[root@master grep]# grep -c "root" /etc/passwd
2
- -E: 開啟正則表達式,相當于使用命令
egrep
查找 /etc/passwd 文件中包含三位數(shù)字的行,例如:
[root@master grep]# grep -E "[[:digit:]]{3}" /etc/passwd
games:x:12:100:games:/usr/games:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
ceph:x:167:167:Ceph daemons:/var/lib/ceph:/sbin/nologin
kube:x:998:996:Kubernetes user:/home/kube:/sbin/nologin
etcd:x:997:993:Etcd user:/var/lib/etcd:/bin/nologin
gluster:x:996:992:GlusterFS daemons:/run/gluster:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
chrony:x:995:991::/var/lib/chrony:/sbin/nologin
redis:x:994:990:Redis Database Server:/var/lib/redis:/sbin/nologin
3. 實例
3.1 需求
編寫一個腳本,獲取 Linux 系統(tǒng)的服務信息,將結(jié)果保存到文件中。
3.2 思路
可以利用函數(shù)來編寫獲取 Linux 服務相關(guān)信息,最后利用重定向?qū)⑿畔⑤敵龅轿募小?/p>
3.3 實現(xiàn)
#!/bin/bash
# Description: service check
# Auth: kaliarch
# Email: kaliarch@163.com
# function: sys check
# Date: 2020-04-11 14:00
# Version: 1.0
[ $(id -u) -gt 0 ] && echo "請用root用戶執(zhí)行此腳本!" && exit 1
sysversion=$(rpm -q centos-release|cut -d- -f3)
line="-------------------------------------------------"
[ -d logs ] || mkdir logs
service_check_file="logs/service-`date +%Y%m%d`.txt"
# 獲取服務信息
function get_service_info() {
port_listen=$(netstat -lntup|grep -v "Active Internet")
kernel_config=$(sysctl -p 2>/dev/null)
if [ ${sysversion} -gt 6 ];then
service_config=$(systemctl list-unit-files --type=service --state=enabled|grep "enabled")
run_service=$(systemctl list-units --type=service --state=running |grep ".service")
else
service_config=$(/sbin/chkconfig | grep -E ":on|:啟用" |column -t)
run_service=$(/sbin/service --status-all|grep -E "running")
fi
cat <<EOF
服務啟動配置:
${service_config}
${line}
運行的服務:
${run_service}
${line}
監(jiān)聽端口:
${port_listen}
${line}
內(nèi)核參考配置:
${kernel_config}
EOF
}
function sys_check() {
get_service_info
echo ${line}
}
# 執(zhí)行主函數(shù)將輸出重定向到文件中
sys_check > ${sys_check_file}
# 執(zhí)行測試
[root@xuel-terraform-cvm-0 ~]# bash sys_check.sh
[root@xuel-terraform-cvm-0 ~]# cat logs/10.0.1.15-20200329.txt
[root@master grep]# cat logs/service-20200411.txt
服務啟動配置:
auditd.service enabled
autovt@.service enabled
ceph-mon@.service enabled
ceph-osd@.service enabled
chronyd.service enabled
crond.service enabled
dbus-org.freedesktop.NetworkManager.service enabled
dbus-org.freedesktop.nm-dispatcher.service enabled
docker.service enabled
etcd.service enabled
gapd.service enabled
getty@.service enabled
irqbalance.service enabled
kdump.service enabled
kubelet.service enabled
microcode.service enabled
NetworkManager-dispatcher.service enabled
NetworkManager.service enabled
postfix.service enabled
rpcbind.service enabled
rsyslog.service enabled
smarteye-server-agent.service enabled
sshd.service enabled
systemd-readahead-collect.service enabled
systemd-readahead-drop.service enabled
systemd-readahead-replay.service enabled
tuned.service enabled
-------------------------------------------------
運行的服務:
auditd.service loaded active running Security Auditing Service
ceph-mon@master.service loaded active running Ceph cluster monitor daemon
ceph-osd@0.service loaded active running Ceph object storage daemon
chronyd.service loaded active running NTP client/server
crond.service loaded active running Command Scheduler
dbus.service loaded active running D-Bus System Message Bus
docker.service loaded active running Docker Application Container Engine
etcd.service loaded active running etcd docker wrapper
gapd.service loaded active running guest agent for pitrix
getty@tty1.service loaded active running Getty on tty1
gssproxy.service loaded active running GSSAPI Proxy Daemon
irqbalance.service loaded active running irqbalance daemon
kubelet.service loaded active running Kubernetes Kubelet Server
NetworkManager.service loaded active running Network Manager
polkit.service loaded active running Authorization Manager
postfix.service loaded active running Postfix Mail Transport Agent
rpcbind.service loaded active running RPC bind service
rsyslog.service loaded active running System Logging Service
smarteye-server-agent.service loaded active running The Smarteye Monitoring of server
sshd.service loaded active running OpenSSH server daemon
systemd-journald.service loaded active running Journal Service
systemd-logind.service loaded active running Login Service
systemd-udevd.service loaded active running udev Kernel Device Manager
tuned.service loaded active running Dynamic System Tuning Daemon
-------------------------------------------------
監(jiān)聽端口:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9099 0.0.0.0:* LISTEN 10444/calico-node
tcp 0 0 172.16.60.2:2379 0.0.0.0:* LISTEN 1321/etcd
tcp6 0 0 :::9353 :::* LISTEN 2058/node-cache
udp 0 0 0.0.0.0:37811 0.0.0.0:* 610/dhclient
udp 0 0 169.254.25.10:53 0.0.0.0:* 2058/node-cache
udp 0 0 0.0.0.0:68 0.0.0.0:* 610/dhclient
udp 0 0 0.0.0.0:111 0.0.0.0:* 1/systemd
udp 0 0 0.0.0.0:123 0.0.0.0:* 530/chronyd
udp 0 0 127.0.0.1:323 0.0.0.0:* 530/chronyd
udp 0 0 0.0.0.0:703 0.0.0.0:* 535/rpcbind
udp6 0 0 :::35267 :::* 610/dhclient
udp6 0 0 :::111 :::* 1/systemd
udp6 0 0 ::1:323 :::* 530/chronyd
udp6 0 0 :::703 :::* 535/rpcbind
-------------------------------------------------
內(nèi)核參考配置:
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_local_reserved_ports = 30000-32767
net.bridge.bridge-nf-call-arptables = 1
-------------------------------------------------
可以看到利用了一個函數(shù)來獲取系統(tǒng)的信息,主函數(shù)將輸出利用重定向方式保存到文件中。
4. 注意事項
- grep 對于文件搜索效率非常高,其不會對源文件作出修改;
- 默認 Linux 系統(tǒng) grep 可以使用參數(shù) - E,-F 來使用 egrep/fgrep;
- 對于復雜的條件可以利用 grep 配合管道多匹配來達到目的。
5. 小結(jié)
grep 命令是 Linux 系統(tǒng)非常強大的文本搜索工具,可以配合正則表達式及其豐富的選項來靈活處理,同時對于復雜的文件搜索,可以配合管道多次匹配來達到搜索的目的,特殊情況下可以利用選項 - E,開啟正則表達式來提供強大的模式匹配處理。