Linux三劍客
grep
-n:列印行號
-A:after 列印過濾內容的後N行
-B:before 列印過濾內容的前N行
-C:center 列印過濾內容的前後N行
-E:支援擴充套件正則 ere grep -E
'root|nginx'
/etc/passwd
-v:取反
-o:只打印匹配到的內容
-w:精確匹配
-P:支援Perl正則
-i:忽略大小寫
-r:遞迴檢索檔案中的內容 grep -r
'www.baidu.com'
./
-R:遞迴檢索檔案中的內容,包括軟連結檔案 grep -R
'www.baidu.com'
./
-l:只顯示檔名
-h:只顯示檔案內容
-f:對比檔案內容,內容少的檔案在前面,內容多的檔案在後面,取反可以看到不同的檔案內容
-c:統計行數,類似於
wc
-l
-G:支援基礎正則 bre
-m:顯示前N行 類似於
head
-n
[root@m01 web]
# grep -r 'www.zls.com' /root/web/
/root/web/css/style.css:www.zls.com
/root/web/js/main.js:www.zls.com
/root/web/index.html:www.zls.com
[root@m01 web]
# grep -lr 'www.zls.com' /root/web/|xargs sed -i.zls 's#www.zls.com#www.baidu.com#g'
awk
sed
-
增
-
刪
-
改
-
查
sed命令執行流程
# 以下是zls.txt檔案內容
1,zls,666
2,wls,777
3,cls,888
4,lls,999
sed -n '3p' zls.txt
命令後,sed都做了啥?sed – 查
sed命令選項 | 選項含義 | sed命令動作 | 動作含義 |
---|---|---|---|
-n | 取消預設輸出 | p | print列印 |
-r | 支援擴充套件正則 | d | delete刪除 |
a | append追加 | ||
i | insert插入 |
p:列印,顯示
## sed顯示單行內容
[root@m01 ~]
# sed '3p' zls.txt
1,zls,666
2,wls,777
3,cls,888
3,cls,888
4,lls,999
## sed取消預設輸出
[root@m01 ~]
# sed -n '3p' zls.txt
3,cls,888
## sed顯示多行內容並取消預設輸出
[root@m01 ~]
# sed -n '1,3p' zls.txt
1,zls,666
2,wls,777
3,cls,888
## sed模糊查詢
[root@m01 ~]
# sed -n '/zls/p' zls.txt
1,zls,666
[root@m01 ~]
# sed -nr '/zls|cls/p' zls.txt
1,zls,666
3,cls,888
[root@m01 ~]
# sed -n '/zls/,/cls/p' zls.txt
1,zls,666
2,wls,777
3,cls,888
## sed實現 grep -A
[root@m01 ~]
# sed -n '/zls/,+2p' zls.txt
1,zls,666
2,wls,777
3,cls,888
[root@m01 ~]
# grep 'zls' -A 2 zls.txt
1,zls,666
2,wls,777
3,cls,888
## sed 隔指定行數讀取一行
[root@m01 ~]
# sed -n '1~2p' zls.txt
1,zls,666
3,cls,888
[root@m01 ~]
# sed -n '1~3p' zls.txt
1,zls,666
4,lls,999
sed – 刪
d:delete 刪除
## 刪除指定行數,不修改原檔案
[root@m01 ~]
# sed '2d' zls.txt
## 刪除最後一行
[root@m01 ~]
# sed '$d' zls.txt
1,zls,666
3,cls,888
## 包含zls的行到cls的行都刪掉
[root@m01 ~]
# sed -n '/zls/,/cls/d' zls.txt
sed – 增
c:replace 替換整行內容
[root@m01 ~]
# cat zls.txt
1,zls,666
3,cls,888
4,lls,999
[root@m01 ~]
# sed '2c2,huanglong,438' zls.txt
1,zls,666
2,huanglong,438
4,lls,999
a:append 追加
[root@m01 ~]
# sed '$a5,huanglong,438' zls.txt
1,zls,666
3,cls,888
4,lls,999
5,huanglong,438
[root@m01 ~]
# sed '2a5,huanglong,438' zls.txt
1,zls,666
3,cls,888
5,huanglong,438
4,lls,999
[root@m01 ~]
# sed '1a2,huanglong,438' zls.txt
1,zls,666
2,huanglong,438
3,cls,888
4,lls,999
i:insert 插入
[root@m01 ~]
# sed '$i2,huanglong,438' zls.txt
1,zls,666
3,cls,888
2,huanglong,438
4,lls,999
[root@m01 ~]
# sed '1i2,huanglong,438' zls.txt
2,huanglong,438
1,zls,666
3,cls,888
4,lls,999
sed – 改
s:substitute 替換
g:global 全域性
s
###g
s@@@g
s啥都行g
## 基礎用法
[root@zabbix01 ~]
# sed 's#zls#ZLS#g' zls.txt
1,ZLS,666
2,wls,777
3,cls,888
4,lls,999
## 使用正則
[root@zabbix01 ~]
# sed 's#[0-9]#666#g' zls.txt
666,zls,666666666
666,wls,666666666
666,cls,666666666
666,lls,666666666
## 後向引用
[root@m01 ~]
# ifconfig eth0|sed -nr 's#^.*inet (.*) net.*#\1#gp'
10.0.0.61
[root@m01 ~]
# ip a s eth1|sed -nr 's#^.*inet (.*)/24.*#\1#gp'
172.16.1.61
sed的模式空間
N:在讀取檔案是,讓sed把下一行內容一起讀進去
awk
awk的內建變數和動作和選項
awk內建變數 | 變數含義 | awk選項 | 選項含義 | awk動作 | 動作含義 |
---|---|---|---|---|---|
NR | Number of Record 行號 | -F | 指定分隔符 | gsub | 替換 |
RS | Record Separator 行的分隔符(\n) | -v | 指定變數(內建變數、自定義變數) | 列印 | |
FS | Field Separator 列的分隔符(空格) | ||||
NF | Number Of Filed 每一行有多少列 |
awk
不是一個命令,是一門語言。awk
又叫做GNU awk,gawk
[root@m01 ~]
# ls -l $(which awk)
lrwxrwxrwx. 1 root root 4 Jul 5 2021 /usr/bin/awk -> gawk
awk執行流程
-
讀取檔案之前
-
BEGIN{}
-
1.讀取檔案之前,先看命令的選項,例如 -F,-v
-
2.如果寫了BEGIN{}則先在BEGIN{}中的指令
-
讀取檔案時
-
{}
-
1.awk在讀取檔案時,也是一行一行的讀\
-
2.讀取一行之後,判斷是否滿足條件,如果是,則執行
-
3.如果不滿足條件,awk繼續讀取下一行,直到滿足條件或者到檔案的最後一行
-
讀取檔案之後
-
END{}
-
1.所有檔案讀取完成之後,走END{}中的指令
[root@m01 ~]
# awk 'BEGIN{xxx}{print $1}END{print 1/3}' zls.txt
[root@m01 ~]
# awk -F: 'BEGIN{print "name","uid"}{print $1,$3}END{print "檔案處理完成"}' /etc/passwd|column -t
[root@m01 ~]
# awk -F: 'BEGIN{print "name","uid","gid"}{print $1,$3,$4}END{print "sb"}' /etc/passwd|column -t
name uid gid
root 0 0
bin 1 1
daemon 2 2
adm 3 4
lp 4 7
sync
5 0
shutdown 6 0
halt 7 0
mail 8 12
operator 11 0
games 12 100
ftp 14 50
awk的行與列
awk取行
NR:Number of Record
[root@m01 ~]
# awk 'NR==1' /etc/passwd
root:x:0:0:root:/root:/bin/bash
## 範圍取行
[root@m01 ~]
# awk 'NR>=1 && NR<=3' /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
[root@m01 ~]
# awk 'NR==1,NR==3' /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
## 包含zls和cls的行
[root@m01 ~]
# awk '/zls|cls/' zls.txt
1,zls,666
3,cls,888
zls,111
[root@m01 ~]
# awk 'NR>=3' zls.txt
/tmp/check_2.txt
/tmp/check_3.txt
/tmp/check_4.txt
/tmp/check_5.txt
3,cls,888
zls,111
4,lls,999
[root@m01 ~]
# awk '/zls/,/cls/' zls.txt
1,zls,666
/tmp/check_1.txt
/tmp/check_2.txt
/tmp/check_3.txt
cls
zls
4,lls,999
cls
### awk的控制結束標記
Record Separator
[root@m01 ~]
# awk -vRS=, 'NR==1' zls.txt
awk取列
FS:內建變數,列分隔符 -F: = -vFS=:
[root@m01 ~]
# awk -vFS=: '{print $1}' /etc/passwd
[root@m01 ~]
# awk -vFS=: '{print $1,$NF}' /etc/passwd
[root@m01 ~]
# awk -F: '{print $1"#"$2"#"$3"#"$4"#"$5"|"$6","$NF}' /etc/passwd
## 修改輸出後內容的分隔符
[root@m01 ~]
# awk -F: -vOFS=# '{print $1,$2,$3,$4,$5,$6,$NF}' /etc/passwd
[root@m01 ~]
# awk -F: '{print $0}' /etc/passwd
awk取行取列
## 取出top中的執行時間
[root@m01 ~]
# top -n1 |awk 'NR==1{print $5}'
1
## 取出網絡卡配置檔案的IP地址
[root@m01 ~]
# awk -F= '/IPADDR/{print $2}' /etc/sysconfig/network-scripts/ifcfg-eth0
10.0.0.61
# 請找出姓氏是張的人,他們第二次捐款的數額及姓名
##### 有問題的寫法 ############
[root@m01 ~]
# cat user.txt
1 Zeng Laoshi 133411023 :110:100:75
2 Deng Ziqi 44002231 :250:10:88
3 Zhang Xinyu 877623568 :120:300:200
4 Gu Linazha 11029987 :120:30:79
5 Di Lireba 253097001 :220:100:200
6 Jiang Shuying 535432779 :309:10:2
7 Ju Jingyi 68005178 :130:280:385
8 Zhang Yuqi 376788757 :500:290:33
9 Wen Zhang 259872003 :100:200:300
[root@m01 ~]
# awk -F '[ :]+' 'BEGIN{print "姓","名","捐款數額"}/^Zhang/{print $2,$3,$6}' user.txt
姓 名 捐款數額
[root@m01 ~]
# awk -F '[ :]+' 'BEGIN{print "姓","名","捐款數額"}/Zhang/{print $2,$3,$6}' user.txt
姓 名 捐款數額
Zhang Xinyu 300
Zhang Yuqi 290
Wen Zhang 200
############# 正確寫法 ################
[root@m01 ~]
# awk -F '[ :]+' 'BEGIN{print "姓","名","捐款數額"}$2~/Zhang/{print $2,$3,$6}' user.txt
姓 名 捐款數額
Zhang Xinyu 300
Zhang Yuqi 290
[root@m01 ~]
# awk -F '[ :]+' 'BEGIN{print "姓","名","捐款數額"}$2~/Zhang/ && $3~/X/{print $2,$3,$6}' user.txt
姓 名 捐款數額
Zhang Xinyu 300
[root@m01 ~]
# awk -F '[ :]+' 'BEGIN{print "姓名","捐款數額"}$2~/Zhang/ && $3~/X/{print $2 $3,$6}' user.txt |column -t
姓名 捐款數額
ZhangXinyu 300
[root@m01 ~]
# awk -F '[ :]+' 'BEGIN{print "姓名","捐款數額"}$2~/Zhang/ && $3~/X/{print $2 $3,$(NF-1)}' user.txt |column -t
姓名 捐款數額
ZhangXinyu 300
### 顯示所有以25開頭的QQ號及姓名
[root@m01 ~]
# awk '$4~/^25/{print $2 $3,$4}' user.txt
DiLireba 253097001
WenZhang 259872003
### 顯示所有QQ號最後一位是1或者3的人,全名及QQ
[root@m01 ~]
# awk '$4~/1$|3$/{print $2$3,$4}' user.txt
ZengLaoshi 133411023
DengZiqi 44002231
DiLireba 253097001
WenZhang 259872003
[root@m01 ~]
# awk '$4~/(1|3)$/{print $2$3,$4}' user.txt
ZengLaoshi 133411023
DengZiqi 44002231
DiLireba 253097001
WenZhang 259872003
[root@m01 ~]
# awk '$4~/[13]$/{print $2$3,$4}' user.txt
ZengLaoshi 133411023
DengZiqi 44002231
DiLireba 253097001
WenZhang 259872003
### 顯示每個捐款值都以$開頭 $110:$00$75
[root@m01 ~]
# awk '{gsub(/:/,"$");print $0}' user.txt
1 Zeng Laoshi 133411023 $110$100
$75
2 Deng Ziqi 44002231 $250$10
$88
3 Zhang Xinyu 877623568 $120$300
$200
4 Gu Linazha 11029987 $120$30
$79
5 Di Lireba 253097001 $220$100
$200
6 Jiang Shuying 535432779 $309$10
$2
7 Ju Jingyi 68005178 $130$280
$385
8 Zhang Yuqi 376788757 $500$290
$33
9 Wen Zhang 259872003 $100$200
$300
[root@m01 ~]
# awk '{gsub(/:/,"$",$5);print $0}' user.txt
1 Zeng Laoshi 133411023
$110
:100:75
2 Deng Ziqi 44002231
$250
:10:88
3 Zhang Xinyu 877623568
$120
:300:200
4 Gu Linazha 11029987
$120
:30:79
5 Di Lireba 253097001
$220
:100:200
6 Jiang Shuying 535432779
$309
:10:2
7 Ju Jingyi 68005178
$130
:280:385
8 Zhang Yuqi 376788757
$500
:290:33
9 Wen Zhang 259872003
$100
:200:300
functiongsub
(){
$1
$2
$3
xxxx
}
gsub(xx,aaa,d)
gsub(
"被替換的內容"
,
"替換的新內容"
)
gsub(
"被替換的內容"
,
"替換的新內容"
,第N列)
## 綜合應用:找出ifconfig中範圍是1-255的數字
[root@m01 ~]
# ifconfig |awk -vRS='[^0-9]+' '$0>=1 && $0<=255'
10
61
255
255
255
10
255
6
80
20
29
3
64
20
29
3
2
5
2
6
1
172
16
1
61
255
255
255
172
16
1
255
6
80
20
29
3
9
64
20
29
3
9
46
9
117
29
7
73
127
1
255
6
1
128
10
awk模式與動作
awk -F:
'NR==1{print $1,$3}'
/etc/passwd
'NR==1{print $1,$3}'
'模式{動作}'
'條件{指令}'
-
正則表示式
# 正則表示式寫法
'/正則表示式/flag'
'$1~/正則表示式/flag'
'$1!~/正則表示式/flag'
只不過我們在awk中很少使用flag
-
比較表示式
NR==1
NR>=10
NR<=100
NR>=1 && NR<=10
$1
>=100
-
範圍模式
## 精確匹配行號:從第10行到第20行
NR==10,NR==20
## 精確匹配字串:從該字串的行到另一個字串所在行
'/root/,/zls/'
'/從哪個字串所在行/,/到那個字串所在行/'#中間的行都包含進去
## 模糊匹配字串:從含有該字串所在行到含有另一字串所在行
'$1~/oo/,$1~/zl/'
-
特殊模式
BEGIN
END
print
-
print列印
-
gsub替換
-
變數賦值
-
統計計算
useradd name;pass=`
echo$RANDOM
|md5sum|
cut
-c 1-10`;
echo$pass
|passwd --stdin name;
echo$pass
:
$user
>> /tmp/user.txt
seq
100|awk
'{print "useradd test"$1";pass=`echo $RANDOM|md5sum|cut -c 1-10`;echo $pass|passwd --stdin test"$1";echo $pass:test"$1" >> /tmp/user.txt"}'
|bash
BEGIN{}
-
1.計算
[root@zabbix01 ~]
# awk 'BEGIN{print 1/3}'
0.333333
-
2.awk功能測試
-
3.輸出表格的表頭
END模式
# 1.統計/etc/service檔案中一共有多少行
[root@m01 ~]
# awk '{hang++;print hang}' /etc/services
1
...
11176
不需要過程,只要結果
[root@m01 ~]
# awk '{hang++}END{print hang}' /etc/services
11176
### 只能統計檔案的所有行數
[root@m01 ~]
# awk 'END{print NR}' /etc/services
11176
### 流氓寫法
[root@m01 ~]
# sed -n '$=' /etc/services
11176
[root@m01 ~]
# grep -c '.*' /etc/services
11176
[root@m01 ~]
# wc -l /etc/services
11176 /etc/services
# 2.統計/etc/service中空行的數量
[root@m01 ~]
# awk '/^$/{print}' /etc/services
[root@m01 ~]
# awk '/^$/{i++}END{print i}' /etc/services
17
# 3.統計出下列檔案中所有人的年齡和
### 指令碼方式
#!/usr/bin/bash
n=0
for
line
in
`
cat
user.txt`;
do
if
[[
$line
=~ [0-9]+ ]];
then
((n+=
$line
))
fi
done
echo$n
### awk方式
[root@m01 ~]
# cat user.txt
姓名 年齡
曾老溼 23
蒼頸空 18
西冶詳 99
[root@m01 ~]
# awk 'NR>1{print $2}' user.txt
23
18
99
[root@m01 ~]
# awk 'NR>1{n+=$2}END{print n}' user.txt
140
# 4.統計nginx日誌中,狀態碼是200的次數以及,狀態碼是200時佔用的流量
[root@m01 ~]
# zcat blog.driverzeng.com_access.log-20220623.gz |awk 'BEGIN{print "狀態碼200的次數","總流量"}$10~/200/{code++;byte+=$11}END{print code,byte}'|column -t
狀態碼200的次數 總流量
3100 190477111
指令碼寫法:
awk
'
BEGIN{
print "狀態碼200的次數","總流量"
}
$10~/200/{
code++;byte+=$11
}
END{
print code,byte
}'
# 5.統計nginx日誌中狀態碼是4xx和5xx的次數及總流量
[root@m01 ~]
# zcat blog.driverzeng.com_access.log-20220623.gz|awk '$10~/^[45]/{i++;n+=$11}END{print i,n}'
580 519243
# 6.綜合應用:分別統計每種狀態碼的次數和每個狀態碼的總流量
zcat blog.driverzeng.com_access.log-20220623.gz |awk
'
BEGIN{
print "狀態碼","總流量"
}
$10~/200/{
i1++;n1+=$11
}
$10~/^3/{
i2++;n2+=$11
}
$10~/^4/{
i3++;n3+=$11
}
$10~/^5/{
i4++;n4+=$11
}
END{
print "200次數:"i1,"200的流量:"n1
print "3xx次數:"i2,"3xx的流量:"n2
print "4xx次數:"i3,"4xx的流量:"n3
print "5xx次數:"i4,"5xx的流量:"n4
}'
|column -t
awk陣列
[root@m01 ~]
# zcat blog.driverzeng.com_access.log-20220623.gz|awk '{print $1}'|sort|uniq -c|sort -nr
[root@m01 ~]
# awk 'BEGIN{array[0]="zls";array[1]="wyk"}'
[root@m01 ~]
# awk 'BEGIN{array[0]="zls";array[1]="wyk";print array[0],array[1]}'
zls wyk
array[0]=
'zls'
array[1]=
'cls'
for
name
in${array[*]}
;
do
echo$name
done
for
(條件){
動作
}
for
條件;
do
動作
done
[root@m01 ~]
# awk 'BEGIN{array[0]="zls";array[1]="wyk";for(num in array){print num}}'
0
1
[root@m01 ~]
# awk 'BEGIN{array[0]="zls";array[1]="wyk";for(num in array){print array[num]}}'
zls
wyk
## 統計nginx日誌中的每一個IP地址訪問的次數
zcat blog.driverzeng.com_access.log-20220623.gz |awk
'{array[$1]++}END{for(ip in array){print ip,array[ip]}}'
#1.取出下列域名並根據域名,進行統計排序處理
https://blog.driverzeng.com/index.html
https://blog.driverzeng.com/1.html
http://post.driverzeng.com/index.html
http://mp3.driverzeng.com/index.html
https://blog.driverzeng.com/3.html
http://post.driverzeng.com/2.html
[root@m01 ~]
# awk -F/ '{domain[$3]++}END{for(name in domain){print name,domain[name]}}' 1.txt
blog.driverzeng.com 3
post.driverzeng.com 2
mp3.driverzeng.com 1
#2.統計nginx日誌中,每個IP訪問使用的流量總和
[root@m01 ~]
# zcat blog.driverzeng.com_access.log-20220623.gz |awk '{ip[$1]++;liuliang[$1]+=$11}END{for(i in ip){print i,ip[i],liuliang[i]}}'
## shell
if
[ 條件 ];
then
動作
fi
if
[ 條件 ];
then
else
fi
if
[ 條件 ];
then
elif
[ 條件 ];
then
else
fi
## awk
if
(條件){
動作
}
if
(條件){
動作
}
else
{
動作
}
if
(條件){
動作
}
elseif
(條件){
動作
}
else
{
動作
}
awk
'{}END{for(條件){if(條件){動作}else if(條件){動作}else{動作}}}'
awk
'{
讀檔案的動作
}END{
for(條件){
if(條件){
動作
}else if(條件){
動作
}else{
動作
}
}
}'
#1.判斷磁碟使用率大於70%,大於顯示磁碟空間不足,不大於顯示正常
## 取出磁碟使用率
[root@m01 ~]
# df -h|awk -F '[ %]+' 'NR==2{if($5>70){print "磁碟空間不足"}else{print "磁碟空間還行"}}'
磁碟空間還行
[root@m01 ~]
# df -h|awk -F '[ %]+' 'NR==2{if($5>70){print "磁碟空間不足"}else{print "磁碟空間還行,當前磁碟使用率:"$5"%"}}'
磁碟空間還行,當前磁碟使用率:9%

文末福利

即將步入2025年,不少小夥伴在考慮來年的工作方向。
僅目前來說,傳統運維衝擊年薪30W+的轉型方向就是SRE&DevOps崗位。









