[linux]七、重定向和文本处理的命令(grep详细用法、diff、生成补丁和打补丁、局域网扫描工具、小数的比较、输出和返回值、shell的多进程思想、查看nginx进程、NR和NF)-3

目录

1、grep

1.1、grep -i和grep -v

1.2、grep -o

1.3、grep -r

1.4、"^"和"$"

1.5、grep -E或者egrep

1.5.1、^$

1.6、grep -A、grep -B和grep -C

1.7、grep小练习

2、diff

2.1、查看文件是否被人修改过(有备份文件的前提下)

2.2、diff命令的输出格式

2.2.1、diff -u

2.3、文件生成补丁和打补丁

2.3.1、生成补丁

2.3.2、打补丁

3、编写脚本

3.1、编程总结

3.1.1、小数的比较

3.1.2、输出值和返回值

3.2、shell里的多进程思想

3.2.1、并行和串行

3.2.2、父进程和子进程的问题

3.3、查看nginx进程是否存在

4、小数的运算

4.1、如何使用bc

4.2、小数的比较

5、awk

5.1、awk进行小数计算

5.2、NR和NF


1、grep

grep通过正则表达式分析程序
       grep, egrep, fgrep - print lines matching a pattern
pattern,模式。其实就是一些条件的组合,用来表达某个意思。主要是一些字符串+数字+特殊符号,组成一个公式。

^、$、|(或者)....,这些叫做元字符,有特殊作用的符号,用来描述其他的字符的字符

# [root@fttsaxf ~]# cat /etc/passwd|egrep  "^c|^f"等价与下边那个命令
[root@fttsaxf ~]# cat /etc/passwd|grep -E "^c|^f"
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
fdd:x:1003:1003::/home/fdd:/bin/bash

1.1、grep -i和grep -v

-i,查找时,忽略大小写。

-v,反转差查找,输出与模式不相符的行

[root@fttsaxf rough_book]# cat phone.txt 
xiaomi
XIAOMI
huawei
HUAWEI  oppo vivo
VIVO
iphone
apple
meizu
kupai
nokia
[root@fttsaxf rough_book]# cat phone.txt | grep -i "xiaomi"
xiaomi
XIAOMI
[root@fttsaxf rough_book]# cat phone.txt | grep -i -n  "xiaomi"
1:xiaomi
2:XIAOMI

1.2、grep -o

只显示匹配的内容

[root@fttsaxf rough_book]# cat phone.txt | grep -o xiaomi
xiaomi

1.3、grep -r

-r,查找某个目录下所有的文件,然后去匹配字符串

[root@fttsaxf rough_book]# grep -r "xiaomi" ./  # 递归的将当前目录下所有的文件都进行查找看是否有"xiaomi"字符串;"/"后边加不加"*",都可以
./phone.txt:xiaomi

1.4、"^"和"$"

"^XX",查找以XX开头的字符串

"XX$",查找以XX结尾的字符串

"^XX$",查找为XX的字符串

[root@fttsaxf rough_book]# cat phone.txt|grep "^x"
xiaomi
[root@fttsaxf rough_book]# cat phone.txt|grep "e$"
iphone
apple
[root@fttsaxf rough_book]# cat phone.txt|grep "^iphone$"
iphone

1.5、grep -E或者egrep

-E,支持更加多的元字符,支持扩展正则表达式(regular expression)。正则表达式是由字符串+数字+特殊符号按照正确的规则组合而成的,要来表达某个意思的公式。例如:
^root -->表示以root开头。^元字符,有特殊作用的字符。

基本正则,里边有很多常见的元字符 ^、$ 、[]。

扩展正则:在基本正则的基础上新加了很多的元字符,例如: "|",表示或者。+、{}、?

grep不能识别扩展正则,所以需要用到egrep或者grep -E

[root@fttsaxf rough_book]# cat phone.txt |grep "^xiao|^a"
[root@fttsaxf rough_book]# cat phone.txt |egrep "^xiao|^a"
xiaomi
apple
[root@fttsaxf rough_book]# cat phone.txt |grep -E "^xiao|^a"
xiaomi
apple

1.5.1、^$

表示空行

[root@fttsaxf rough_book]# cat phone.txt 
xiaomi
XIAOMI
huawei

HUAWEI  oppo vivo
VIVO
iphone
apple
meizu
kupai
#
nokia
[root@fttsaxf rough_book]# cat phone.txt |egrep -n "^#|^$"  # 找出空行和注释行
4:
11:#
[root@fttsaxf rough_book]# cat phone.txt |egrep  -v "^#|^$"  # 找出文章中的有效行
xiaomi
XIAOMI
huawei
HUAWEI  oppo vivo
VIVO
iphone
apple
meizu
kupai
nokia

1.6、grep -A、grep -B和grep -C

[root@fttsaxf rough_book]# cat phone.txt |grep -A 2 HUAWEI  # 查找出HUAWEI,并且显示出后面2行
HUAWEI  oppo vivo
VIVO
iphone
[root@fttsaxf rough_book]# cat phone.txt |egrep -B 2 iphone  # 查找出iphone,并且显示出前边2行
HUAWEI  oppo vivo
VIVO
iphone
[root@fttsaxf rough_book]# cat phone.txt |egrep -C 2 iphone  # 查找出iphone,并显示出前后2行
HUAWEI  oppo vivo
VIVO
iphone
apple
meizu

1.7、grep小练习

#第一题:
[root@fttsaxf rough_book]# cp /etc/passwd .
#第二题:
[root@fttsaxf rough_book]# cat passwd |egrep "^ftp|^mail"
#第三题:
[root@fttsaxf rough_book]# cat passwd |egrep -v "^m|^r|^f"
[root@fttsaxf rough_book]# cat passwd |egrep -v "^[rmf]"
[root@fttsaxf rough_book]# cat passwd |egrep  "^[^rmf]"
"""
[^rmf] 不是rmf字符
^,在中括号里边表示取反;在外边表示以什么开头
"""
#第四题:
[root@fttsaxf rough_book]# cat passwd | grep "bash$"
#第五题:
[root@fttsaxf rough_book]# cat /etc/login.defs |egrep -v "^#|^$"
#第六题:
[root@fttsaxf rough_book]# cat /var/log/messages|egrep -w  "[a-Z]{16}"
[root@fttsaxf rough_book]# cat /var/log/messages|egrep "\<[a-Z]{16}\>"
[root@fttsaxf rough_book]# cat /var/log/messages|egrep "\<[a-Z]{16}\b"
Feb 13 23:08:44 fttsaxf NetworkManager[757]: <info>  [1644764924.7576] settings: Loaded settings plugin: NMSKeyfilePlugin (internal)
'''
单词的界定符号
\< 以什么开头
\> 单词以什么结尾
\b 可以单独取代\<或者\>

[root@fttsaxf rough_book]# cat phone.txt |egrep "\<iphone"  # 查看单词以"iphone"开头的
iphone
iphone11
iphone13pro
[root@fttsaxf rough_book]# cat phone.txt |egrep "iphone\>"  # 查看单词以"iphone"结尾的
iphone
maxiphone
[root@fttsaxf rough_book]# cat phone.txt |egrep "\<iphone\>"  ## 查看单词"iphone"
iphone
'''
#第七题:
[root@fttsaxf rough_book]# cat passwd |grep "bash$"|grep "liu"
[root@fttsaxf rough_book]# cat passwd |egrep "liu.*bash"
'''
.*,是正则里表示任意字符的意思
'''
#第八题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep -v "^$|^#"
#第九题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep "[0-9][0-9]"
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep "[0-9]{2}"
'''
a{2},表示花括号前边的a连续出现两次
abc{2},表示花括号前边的c连续出现两次。能够匹配的字符串是"abcc"
[0-9]{2},表示从0到9里可以取2次的数字,随便取,取2次
[0-9]{2,5},表示从0到9里可以取2到5次的数字,随便取,最少取2次,最多取5次
[0-9]{2,},表示从0到9里可以取至少两次的数字

'''
#第十题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep "[^0-Z]" 
#第十一题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep  -v "[0-9]" 
#第十二题:
'''
IP地址是由四个0~255的数字和"."组成
"\.",表示"."符号
".",在正则里表示任意单个字符
'''
[root@fttsaxf rough_book]# cat /var/log/secure|egrep "[0-9]{,3}\.[0-9]{1,3}"

2、diff

用途:比较两个文件之间的差异,输出结果为两个文件的不同之处。

2.1、查看文件是否被人修改过(有备份文件的前提下)

[root@fttsaxf rough_book]# diff passwd passwd.backup 
2,5d1
< 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
# 这里是在passwd中增加了几行。要是输出来之后没有输出,则表示没有修改
[root@fttsaxf rough_book]# diff phone.txt phone.txt.backup 
13c13
< iphpne11
---
> iphone11
# md5sum,根据文件里的内容计算出一个固定的值。如果文件修改了,里边的内容发生了变化,计算出来的值就会不一样
[root@fttsaxf rough_book]# md5sum phone.txt  # 这里使用了"md5"
6f863f83adf0802cf683d20e03058153  phone.txt
[root@fttsaxf rough_book]# vim phone.txt
[root@fttsaxf rough_book]# md5sum phone.txt
583c051794779cc8aaa0e3b60cf898d3  phone.txt

2.2、diff命令的输出格式

2.2.1、diff -u

[root@fttsaxf rough_book]# diff -u phone.txt phone.txt.backup 
--- phone.txt	2022-02-16 14:55:51.675261916 +0800
+++ phone.txt.backup	2022-02-16 14:47:50.202355604 +0800
@@ -1,10 +1,10 @@
 xiaomi
 XIAOMI
-huwei
+huawei
 
 HUAWEI  oppo vivo
 VIVO
-ipnone
+iphone
 apple
 meizu
[root@fttsaxf rough_book]# echo $?  
1  # 有区别,返回值为"1"
[root@fttsaxf rough_book]# diff test test.backup 
[root@fttsaxf rough_book]# echo $?
0  # 没有区别,返回值为"0"

2.3、文件生成补丁和打补丁

补丁:程序更新了的部分。程序是人编写的,可能含有漏洞,发现漏洞之后,需要编写弥补这个漏洞的程序,也就是补丁

2.3.1、生成补丁

# 将phone和phone_v2的差异重定向到一个文件里,这个文件就是补丁包
[root@fttsaxf rough_book]# diff -u phone phone_v2 >phone.patch  # 打补丁
[root@fttsaxf rough_book]# ls
phone  phone.patch  phone_v2
[root@fttsaxf rough_book]# cat phone.patch 
--- phone	2022-02-16 15:11:21.534180101 +0800
+++ phone_v2	2022-02-16 15:17:11.332927027 +0800
@@ -13,3 +13,4 @@
 iphone11
 iphone13pro
 maxiphone
+new-phone:iphone19

2.3.2、打补丁

[root@fttsaxf rough_book]# patch phone <phone.patch  # 将补丁加入phone中
patching file phone
[root@fttsaxf rough_book]# diff phone phone_v2  # 对比差异发现没有区别了

3、编写脚本

脚本的shell代码为:

#!/bin/bash

# 编写菜单
menu(){
	echo "================================"
	echo  "1.monitor memory usage"
	echo  "2.scan LAN"
	echo  "3.monitor /etc/passwd and /etc/hosts"
	echo  "4.monitor nginx deamon"
	echo  "5.exit"
	echo "================================"
	read -p "请输入你的选择:"  option
}

# 系统性能监控
usage(){
	>1.txt || touch  1.txt
	free -m |tail -n +2|awk '{print $1,$2,$3}' >1.txt  # 将进程名、总共内存和已使用内容截取出来放入1.txt中
	while read name total used
	do
		# 计算得到内存使用率情况,因为linux里边的默认的除是地板除
		pro=$(printf "%.5f" `echo "scale=5;$used/$total"|bc`)
		if (( $( echo "$pro > 0.7"|bc ) == 1 ))
		then
			echo "$name,这台机器的内存使用为$por,超过了70%,请注意"
		else
			echo "$name,这台机器的内存使用为$pro,没有超标"
		fi
	done < 1.txt
: <<EOF  # 这里只是一个注释
-gt,表示大于
-lt,表示小于
-eq,表示等于
-ne,表示不等于
-ge,表示大于等于
-le,表示小于等于
(( 9 > 8 )) 等效于 [ 9 -gt 8 ],以此类推
EOF
}

# 局域网扫描工具
scan(){
	>ip.txt # ">",重定向,有就清空,没有就新建
	echo "下面是正在使用的局域网:" >ip.txt
	for ip in 192.168.29.{0..255}
	do
		(
		if ping -c 1 $ip &>/dev/null ;then
			echo $ip >>ip.txt
			continue
		fi
		break
		)&
	done	
	echo "###################"
	echo "全部局域网已经扫描完成"
	echo  "#################"
	total=$(cat ip.txt|wc -l)  # 统计ip.txt中有多少行
	if (( $total > 1 ));then  # 因为我之前输入了一个“下面是正在使用的局域网”,所以就是该文件行数大于1才会有ip地址正在使用
		cat ip.txt
	else
		echo "局域网内没有IP地址在使用"
	fi
}	

# 监控文件是否被修改
# tamper,做手脚;破坏的意思
tamper(){
	while :
	do
		# 作比较之前要使用cp命令把diff后边第一个文件复制到你要比较的位置,切记不要使用mv!!!!
		num_1=$(diff /etc/passwd /root/linux/script/menu/passwd.backup|wc -l )
		if (( $num_1 == 0 ))  # 统计行数为0的话,就是前一个文件没有被修改。因为后一个文件是前一个文件的备份
		then
			echo "/etc/passwd 文件没有被修改"
		else
			echo "/etc/passwd 文件被修改了"
		fi
		sleep 1
		num_2=$(diff /etc/hosts  /root/linux/script/menu/hosts.backup|wc -l)
		if  (( $num_2 == 0 ))
		then
			echo "/etc/hosts  文件没有被修改"
		else
			echo "/etc/hosts  文件被修改了"
		fi
		break
	done
}

# 监控nginx进程是否存在,存在或者不存在都给予提醒
process(){
	if pidof nginx &>/dev/null;then
		echo "nginx进程存在"
	else
		echo "nginx进程不存在"
	fi	
}

while :
do
	menu
	case $option in
		1)
			echo "现在正在进行系统性能监控"
			echo "################"
			usage
			;;
		2)
			echo "现在正在进行局域网扫描"
			scan
			;;
		3)
			echo "现在正在查看监控文件是否被修改"
			echo "################"
			tamper
			;;
		4)
			echo "现在正在查看监控nginx进程是否存在"
			echo "######################"
			process
			;;
		5)
			echo "成功退出"
			exit
			;;
		*)
			echo "请您配合输入1-5的数字"
			;;		
	esac
	echo
	read -p "请敲击"Enter"键继续执行你想要的功能"
	clear
done

3.1、编程总结

3.1.1、小数的比较

shell里默认双圆括号"(())"支持整数的运算和比较,但是不支持小数的。python都可以支持的。

[root@fttsaxf menu]# ((9>5))
[root@fttsaxf menu]# echo $?
0
[root@fttsaxf menu]# ((0.1>0.2))
-bash: ((: 0.1>0.2: 语法错误: 无效的算术运算符 (错误符号是 ".1>0.2")
[root@fttsaxf menu]# num=`echo "100.7 > 91.8"|bc`  # 这里使用的反引号"`"
[root@fttsaxf menu]# num1=$(echo "100.7 > 91.8"|bc)  # 这里使用了"$()",推荐使用这个
[root@fttsaxf menu]# echo $num $num1
1 1
# 以上两种写法都是一样的
# 另外awk也可以实现小数的计算

3.1.2、输出值和返回值

输出值:程序运行的过程中的输出内容 

返回值:命令是否执行成功。
函数的返回值:return(退出函数),后面不接数字默认情况下是0
脚本的返回值:exit(退出脚本),后面不接数字默认情况下是0

3.2、shell里的多进程思想

3.2.1、并行和串行

并行:同时执行--》速度快
串行:一个一个的执行,按照顺序 --》速度慢

for循环同时产生254个子进程去ping不同的ip地址;(命令) & 产生子bash进程去执行命令放在后台执行。{命令}&也可以

3.2.2、父进程和子进程的问题

当父进程结束的时候,会给所有的子进程发信号,告诉内核杀死所有的子进程。当父进程的程序执行完毕,但是子进程的程序没有执行完,若没有做修改,当父进程做完,子进程就会被全部杀死。

怎么防止这个问题呢?

可以使用wait命令 

 注意:wait是要放在for循环外边的

3.3、查看nginx进程是否存在

if  命令
then         
        命令1
else
        命令2
fi

当我们要使用返回值和if结合的时候,我们可以直接把命令放在if后边,当后边命令执行成功(也就是返回值为0)就会执行if第一个命令,要是没有成功就会执行第二个命令

4、小数的运算

bc

4.1、如何使用bc

bc有两种方法可以调用

[root@fttsaxf menu]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
9 + 6
15
quit
[root@fttsaxf menu]# echo "9 + 6.9"|bc
15.9

4.2、小数的比较

-gt,表示大于
-lt,表示小于
-eq,表示等于
-ne,表示不等于
-ge,表示大于等于
-le,表示小于等于
(( 9 > 8 )) 等效于 [ 9 -gt 8 ],以此类推

5、awk

awk命令的完整语法

 awk的命令的执行过程:BEGIN和END部分只是执行一次,pattern{commands}中间部分每一行都执行一次

[root@fttsaxf menu]# awk -F ":" 'BEGIN{print "#########start###########" } $3>1000 {print $1,$3,$7 } END {print "#####################end###############"}'  /etc/passwd
#########start###########
bagnyou 1001 /bin/bash
bangyou 1002 /bin/bash
fdd 1003 /bin/bash
chenxw 1004 /bin/bash
caohx 1005 /bin/bash
zhangjian 1006 /bin/bash
fzt 1007 /bin/bash
califeng 1008 /bin/bash
cali123 1009 /bin/bash
ysdf 1010 /bin/bash
fja 1011 /bin/bash
dfja 1012 /bin/bash
dfjalsk 1013 /bin/bash
#####################end###############

5.1、awk进行小数计算

[root@fttsaxf menu]# awk 'BEGIN{print 89 + 57}'
146
[root@fttsaxf menu]# awk 'BEGIN{print 89 + 57.5}'
146.5
[root@fttsaxf menu]# awk 'BEGIN{printf "%.2f\n",'$a'/'$b'}'
0.33
# %.2f\n,指定awk计算的精度,小数点的数位为2位

5.2、NR和NF

NR:是awk里表示每行里的行号(number of records),记录的行号,一行就是一条记录
NF:是awk里表示一行有多少个字段数(number of fields)
它们都是awk里的内部变量

[root@fttsaxf menu]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1819         206        1470           9         142        1465
Swap:          2047           0        2047
[root@fttsaxf menu]# free -m |awk 'NR==2{print $3/$2}'
0.113249
[root@fttsaxf menu]# free -m |awk 'NR==2{print $3/$2*100}'
11.3249
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FanMY_71

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值