mycpen

Mycpen

记录学习历程与受益知识
github
telegram
bilibili

13_Linux基礎-SHELL命令-wc-diff-patch-bc-awk

一。回顧#

sort#

sort

格式:sort 选项 文件
-n	按數值進行排序
-r	降序排序
-k	指定排序的列
-t	指定分隔符
-u	去重

uniq#

uniq

格式:uniq 选项 文件
-c	統計每列在文本中出現的次數
-u	僅顯示出現一次的行
-d	僅顯示重複出現的行

cut#

cut

格式:cut 选项 提取範圍 文件
-d	指定分隔符
-f	指定顯示的特定字段
-c	指定特定字符

文本三劍客#

grep 過濾 通用的正則表達式分析程序
grep [选项]... 模式 目标文件
-i	不區分大小寫
-v	反轉查找,不顯示包含指定字符的行
-o	顯示匹配的內容,並且換行顯示
-n	顯示出過濾出來的行的行號
-r	遞歸查找指定目錄下所有的文件(包括其子目錄)
-E	支持更多的正則擴展表達式

正則表達式#

^aa	以aa開頭的行
Aa$	以aa結尾的行

通配符#

*	表示匹配前一項任意次
?	表示匹配前一次0次或1次
+	表示匹配前一項一次到多次
.	(佔位符)表示除換行符之外的任意字符
{n,m}		匹配n到m次
{,n}		匹配0次到n次
{m,}		匹配m次以上
[]集合表示
[a-zA-Z]
[0-9]
[^a]		表示不取a
示例
---------------------------------------------------------------------------------------------------------------------------------
# grep -E "a.*c" grep_test.txt 				# 注:.* 匹配前一項 . 0次或任意次
# grep -E "a*c" abc.txt --color=auto		# 注:*  匹配前一項 a 0次或任意次
# grep -E "a+c" abc.txt --color=auto		# 注:+  匹配前一項 a 1次或多次

二. wc#

wc(字數統計)命令

格式:wc [选项]... 目标文件...

  • -l:統計行數
  • -w:統計字數 (前後都是空白的一組字符)
  • -c:統計字符數(可見和不可見的字符)

注:wc 文本操作命令,可以直接接文本,不需要用 cat

[root@sanchuang-linux ~]# cat wc_test.txt 
a b c
aa bb cc
xyz
1234
aa-bb

示例
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# wc -l wc_test.txt 	# 注:統計行數
5 wc_test.txt
[root@sanchuang-linux ~]# wc -w wc_test.txt 	# 注:統計字數
9 wc_test.txt
[root@sanchuang-linux ~]# wc -c wc_test.txt 	# 注:統計字符數
30 wc_test.txt
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# cat wc_test.txt|wc -c		# 寫法2:cat
30
[root@sanchuang-linux ~]# wc -c < wc_test.txt 		# 寫法3:重定向
30

三. diff#

diff 命令

  • 比較兩個文件之間的差異
  • 輸出結果為兩個文件的不同之處

diff 命令的輸出格式

  • 標準 diff
  • -u:會將不同的地方放在一起,緊湊易讀
  • -r: 遞歸比較目錄下的所有文件

利用 diff 命令生成補丁

  • diff -u test1 test2 > test.patch
[root@sanchuang-linux ~]# cat diff_1_test.txt
aa
bb
cc
xx
[root@sanchuang-linux ~]# cat diff_2_test.txt
aa
bb
xx

示例1
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# diff diff_1_test.txt diff_2_test.txt 
3d2							# 注:3d2  文件1個第3行 需要刪除 就會和 文件2相同
< cc						# 注:文件1 中的cc
============================================================================================

[root@sanchuang-linux ~]# cat diff_1_test.txt
aa
bb
cc
xx
gg
[root@sanchuang-linux ~]# cat diff_2_test.txt
aa
bb
dd
xx
ee

示例2
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# diff diff_1_test.txt diff_2_test.txt 
3c3											# 注:第3行
< cc										# 注:文件1 中的cc
---
> dd										# 注:文件2 中的dd
5c5											# 注:第5行
< gg										# 注:文件1 中的gg
---
> ee										# 注:文件2 中的ee
--------------------------------------------------------------------------------------------
============================================================================================

示例3:-u:會將不同的地方放在一起,緊湊易讀
[root@sanchuang-linux ~]# diff -u diff_1_test.txt diff_2_test.txt 
--- diff_1_test.txt	2020-10-30 11:50:45.784010843 +0800
+++ diff_2_test.txt	2020-10-30 11:51:11.475010836 +0800
@@ -1,5 +1,5 @@
 aa
 bb
-cc											# 注:理解為 左 - 右 +
+dd											# 注:或者理解為 左邊 -cc +dd 就和右邊相同
 xx
-gg
+ee

四. patch#

patch 命令:

  • 用途:用來打補丁修補文件
  • 格式:patch [选项] 原始文件 < 补丁文件
  • -pN: N 表示忽略 N 層路徑
  • -R: 還原到舊版本

注意事項

  • 如果打多個補丁,注意先後順序
  • 打補丁前不要修改源文件
示例
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# yum install patch
[root@sanchuang-linux ~]# diff diff_1_test.txt diff_2_test.txt 	
3c3							# 注:差異內容
< cc
---
> dd
5c5
< gg
---
> ee

#注:差異文件又叫補丁文件
#注:生成的是文件1的補丁文件
[root@sanchuang-linux ~]# diff -u diff_1_test.txt diff_2_test.txt > diff_test.patch # 注:1的補丁
[root@sanchuang-linux ~]# cat diff_test.patch 		#注:補丁文件
--- diff_1_test.txt	2020-10-30 11:50:45.784010843 +0800
+++ diff_2_test.txt	2020-10-30 11:51:11.475010836 +0800
@@ -1,5 +1,5 @@
 aa
 bb
-cc
+dd
 xx
-gg
+ee
[root@sanchuang-linux ~]# patch diff_1_test.txt < diff_test.patch 	# 注:打補丁
patching file diff_1_test.txt
[root@sanchuang-linux ~]# cat diff_1_test.txt 						# 注:打補丁
aa
bb
dd
xx
ee
[root@sanchuang-linux ~]# cat diff_2_test.txt 		# 注:文件1、2內容相同
aa
bb
dd
xx
ee

五. grep -A\-B#

-A:找到匹配行以及後幾行

-B:輸出匹配行以及前幾行

示例
[root@localhost ~]# grep -A 3 quit /etc/passwd		# 注:找到匹配行以及後幾行
[root@localhost ~]# grep -B 3 quit /etc/passwd		# 注:輸出匹配行以及前幾行

六. free -g#

看內存使用率 free -g

[root@sanchuang-linux ~]# free -g		# 注:看內存使用率 ,-g單位G , -m單位M
              total        used        free      shared  buff/cache   available
Mem:              1           0           1           0           0           1
Swap:             1           0           1
[root@sanchuang-linux ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1800         272        1101           8         426        1363
Swap:          2047           0        2047

七。編寫腳本#

實現以下功能
1、監控內存使用情況,如果內存使用率大於百分之80,給予提醒
	total free 使用率
2、掃描局域網ip,檢查哪些ip地址正在使用
	ping -c 1		# 注:發送1個包
3、監控文件/etc/passwd是否被修改,每隔5分鐘監控一次
	diff
	md5sum	# md5值,文件的唯一標識
4、監控nginx進程是否存在,不存在就給予相應提醒
	pidof nginx
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# md5sum abc.txt 			# 注:md5值
2416b02c3d9d753f48cf49dbb5f1de94  abc.txt
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# pidof nginx				# 注:顯示指定程序的進程號
12767 12766 12765

7.1 監控內存使用情況,如果內存使用率大於百分之 80,給予提醒#

​ total free 使用率

示例
--------------------------------------------------------------------------------------------
#!/bin/bash
function mem(){
    total=`free -m|grep -i mem|tr -s " "|cut -d " " -f2`
    #free=`free -m|grep -i mem|tr -s " "|cut -d " " -f4`
    used=`free -m|grep -i mem|tr -s " "|cut -d " " -f3`
    used_rate=`echo "scale=4;$used/$total" |bc`
    #used_1=`echo "$total*0.8"|bc `
    result=` echo "$used_rate>0.8"|bc `
    echo $result
    if (( $result  == 1  ))
    then
        echo -e "\e[31m使用率超過80%,請及時對內存擴容,以免不必要的損失\e[0m"
    else
        echo  " nothing to do"
    fi
}
mem
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# bash mem_test.sh
0
 nothing to do
============================================================================================
知識點7.1.1 bc 命令
菜鳥教程:https://www.runoob.com/linux/linux-comm-bc.html
bc 命令是任意精度計算器語言,通常在linux下當計算器用
[root@localhost ~]# yum install bc -y
[root@localhost ~]# used=`free -m|grep -i mem|tr -s " "|cut -d " " -f3`
[root@localhost ~]# total=`free -m|grep -i mem|tr -s " "|cut -d " " -f2`
[root@localhost ~]# echo "scale=2;$used/$total" |bc	# 注:保留2位小數
.16
[root@localhost ~]# echo "scale=3;$used/$total" |bc	# 注:保留3位小數
.165
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# free -m|grep -i mem|tr -s " "|cut -d " " -f2 # 注:-i 不區分大小寫
1800
[root@sanchuang-linux ~]# use_rate=`echo "scale=4;$used/$total" |bc`
[root@sanchuang-linux ~]# echo "$use_rate>0.8"|bc	# 注:為假返回0
0
[root@sanchuang-linux ~]# echo "0.7>0.8"|bc			# 注:為假返回0
0
[root@sanchuang-linux ~]# echo "0.9>0.8"|bc			# 注:為真返回1
1		# 注:這返回的應該是布爾值0假1真,而不是命令執行失敗的值。$?都為0 ,命令執行成功
############################################################################################
知識點7.1.2 小數的運算
小數的運算:
1、可以使用bc
[root@sanchuang-linux ~]# echo "scale=3;1/3"|bc		# 注:保留3位小數
.333
[root@sanchuang-linux ~]# echo "0.7>0.8"|bc			# 注:不成立返回0
0
[root@sanchuang-linux ~]# echo "0.9>0.8"|bc			# 注:成立返回1
1

2、awk 選項
語法:awk 選項 ‘模式+動作’ 文件
常用選項:
-F	指定分隔符

內置變量
NR	awk里表示每一行的行號
NF	awk的列號

模式

示例
--------------------------------------------------------------------------------------------
[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           3770         195        3274          11         300        3348
Swap:          2047           0        2047
[root@localhost ~]# free -m|awk 'NR==2{print $2}'		# 注:打印第二行 第2個變量
3770													# 注:NR 行號 , $2 第2個變量
[root@localhost ~]# free -m|awk 'NR==2{print $3}'		# 注:打印第二行 第3個變量
194
============================================================================================
[root@sanchuang-linux ~]# free -m|awk '/Mem/{print $3/$2}'		# 注:計算小數,過濾出Mem
0.156111														# 注:過濾出Mem 這1行
[root@sanchuang-linux ~]# free -m|awk '/Mem/{printf "%.2f\n", $3/$2}'	# 注:保留2位的浮點數
0.16															# 注:\n換行輸出

7.2 掃描局域網 ip, 檢查哪些 ip 地址正在使用#

​ ping -c 1 # 注:發送 1 個包

方法1
--------------------------------------------------------------------------------------------
scan_ip(){
    for ip in `seq 255`
    do
        ( ip_full=192.168.0.$ip
        ping -c 1 $ip_full &>/dev/null && echo $ip_full >>up.txt || echo $ip_full >>down.txt
        ) &	# 注:放到後台子進程執行
    done
wait # 父進程等待子進程執行完成之後再退出
}
scan_ip

方法2
--------------------------------------------------------------------------------------------
scan_ip(){
    for ip in 192.168.0.{1..255}					# 注:1-255可以這麼寫
    do
        ( 
        ping -c 1 $ip &>/dev/null && echo $ip >>up.txt || echo $ip >>down.txt
        ) & 
    done
wait #注:作用:父進程等待子進程結束之後再退出
}
scan_ip
注:後台進程
命令 &	   產生子bash進程去執行命令的任務
wait		父進程等待子進程結束之後再退出
============================================================================================
[root@sanchuang-linux ~]# ip=45
[root@sanchuang-linux ~]# ip_full=192.168.0.$ip			# 注:shell 字符串的拼接
[root@sanchuang-linux ~]# echo $ip_full 
192.168.0.45
[root@sanchuang-linux ~]# top							# 注:查看cpu

7.3 監控 nginx 進程是否存在,不存在就給予相應提醒#

​ pidof nginx

示例
--------------------------------------------------------------------------------------------
check_nginx(){
    pidof nginx && echo "nginx is running" || echo "nginx is down"
    #if [[ $? -eq 0 ]]
    #then
    #    echo "nginx is running"
    #fi
}
check_nginx
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# pidof nginx
12767 12766 12765
[root@sanchuang-linux ~]# echo $?					# 注:返回值為0表示成功
0

7.4 監控文件 /etc/passwd 是否被修改,每隔 5 分鐘監控一次#

​ diff

​ md5sum # md5 值,文件的唯一標識

示例
--------------------------------------------------------------------------------------------
check_monitor(){
    check_num=`differ /etc/passwd /lianxi/passwd |wc -l`
    [[ check_num -eq 0 ]] && echo "文件未被修改" || echo "文件已被修改"
}
check_monitor
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# cp /etc/passwd /lianxi/passwd
cp:是否覆蓋'/lianxi/passwd' y
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd
[root@sanchuang-linux ~]# echo $?	# 注:即使文件不被修改,返回也為0 (理解為命令執行成功)
0									# 注:所以不能直接用類三元運算 去判斷
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd|wc
      0       0       0
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd|wc -l
0
#注:判定依據 diff 是否輸出內容
	沒有輸出內容,wc -l 行數為0,說明文件未被修改
#注:文件是否被修改,想到diff命令

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。