Linux笔记 | Shell编程(下)


01 正则表达式入门

在Linux中,grep,sed,awk等文本工具都支持通过正则表达式进行模糊匹配。

# 匹配所有包含abc的行
cat /root/hello.txt | grep abc

# 匹配以ab开头的所有行
cat /root/hello.txt | grep ^ab

# 匹配以bc结尾的所有行
cat /root/hello.txt | grep bc$

# .可匹配任意一个字符
cat /root/hello.txt | grep r..t  # 匹配所有包含rxxt的行 例如root rabt rxyt

# *匹配任意次的某字符
cat /root/hello.txt | grep ro*t  # 匹配包含rt rot root rooot的所有行

# 匹配开头是a 结尾是bash的所有行
cat /root/hello.txt | grep ^a.*bash$  # 扩展:^a.*var.*bash$

[]表示匹配某个范围内的一个字符

# 匹配6或8(包含6或8的行,下同)
cat /root/hello.txt | grep [6,8]

# 匹配一个数字
cat /root/hello.txt | grep [0-9]

# 匹配任意长度的数字字符串
cat /root/hello.txt | grep [0-9]*

# 匹配一个小写字母字符
cat /root/hello.txt | grep [a-z]

# 匹配任意长度的字母字符串
cat /root/hello.txt | grep [a-z]*

# 匹配一个a-c或e-f之间的任意字符串(a b c e f)
cat /root/hello.txt | grep [a-c,e-f]

# 会匹配rt rat rabt rbact rccbbat等所有行
cat /root/hello.txt | grep r[a,b,c]*t

使用\匹配特殊字符

# 匹配包含$符号的行 注意需要使用单引号括起来
cat /root/hello.txt | grep '\$'

练习:匹配手机号

# 普通写法
echo "13456789001" | grep ^1[34578][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$

# 支持扩展表达式的写法 使用-E参数 {9}表示重复9次
echo "13456789001" | grep -E ^1[34578][0-9]{9}$

02 文本处理工具

2.1 cut工具

语法:
cut [参数] 文件名
-f 提取第几列
-d 指定分隔符 默认为\t
示例:

# 有如下内容的文件 空格分隔
a b c
d e f
good bad ok

# 获取第一列(指定以空格分隔) 输出 a d good(三行)
cut -d " " -f 1 cut.txt

# 获取第二三列
cut -d " " -f 2,3 cut.txt

# 获取系统PATH变量值中第2个":"开始后的所有路径
echo $PATH | cut -d ":" -f 3-

# 获取ip地址
ifconfig | grep netmask | cut -d " " -f 10

2.2 awk工具

awk是一个强大的文本分析工具,把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
语法:
awk [参数] '/pattern1/{action1} /pattern2/{action2} ...' 文件名
pattern awk在数据中查找的内容(正则表达式)
action 找到匹配内容时执行的一系列命令
-F 指定输入文件分割符
-v 赋值一个用户定义变量
示例:

# 搜索passwd文件中以root关键字开头的所有行 并输出该行的第7列
cat /etc/passwd | awk -F ":" '/^root/{print $7}'  # print是awk提供的 用于输出

# 搜索passwd文件中以root关键字开头的所有行 并输出该行的第1列和第7列 中间以,分隔
cat /etc/passwd | awk -F ":" '/^root/{print $1","$7}'

# 显示passwd第1列和第7列 以,分隔 且在首行前添加列名user shell 在尾行后添加end of file字样
cat /etc/passwd | awk -F ":" 'BEGIN{print "user shell"} {print $1","$7} END{print "end of file"}'

# 将passwd文件中的用户id增加数值1并输出
cat /etc/passwd | awk -F ":" '{print $3+1}'

# 将passwd文件中的用户id增加数值2并输出(使用变量)
cat /etc/passwd | awk -v n=2 -F ":" '{print $3+n}'

awk内置变量
FILENAME 文件名
NR 已读的记录数(行号)
NF 浏览记录的域的个数(切割后列的个数)

# 使用内置变量
awk -F ":" '{print "文件名:"FILENAME " 行号:"NR " 列数:"NF}' /etc/passwd

# 输出空行的行号
ifconfig | grep -n ^$  # -n表示输出显示行号
ifconfig | awk '/^$/{print NR}'  # 方式二

# 输出IP地址
ifconfig | awk '/netmask/{print $2}'

03 综合运用 - 发送消息

  • 需求
    实现一个向某个用户快速发送消息的脚本,输入用户名作为第一个参数,后面直接跟要发送的消息。脚本需要检测用户是否登录在系统中、是否打开消息功能,以及当前发送消息是否为空。
  • 提示
    使用Linux自带的mesg和write工具,向同一系统的其他用户发送消息。
#!/bin/bash
# 查看用户是否登录 第1个$1是用户的输入 第1个$1是切分后的第1个值
login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')  # -i表示忽略大小写 -m 1表示筛选出来取第1行
if [ -z $login_user ]  # -z表示判断是否为空
then
	echo "$1 不在线"
	echo "脚本退出..."
	exit
fi

# 查看用户是否能接收消息
is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')  # -T参数可查看用户是否开启了消息接收功能
if [ $is_allowed != "+" ]
then
	echo "$1 没有开启消息功能"
	echo "脚本退出..."
	exit
fi

# 确认是否有消息发送
if [ -z $2 ]
then
	echo "消息为空 无法发送"
	echo "脚本退出..."
	exit
fi

# 从参数中获取要发送的消息
msg=$(echo $* | cut -d " " -f 2-)  # 以空格分隔 取第2列及以后的所有参数视为要发送的消息

# 获取接收用户登录的终端
user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')

# 写入要发送的消息
echo $msg | write $login_user $user_terminal
if [ $? -eq 0 ]
then
	echo "发送成功"
else
	echo "发送失败"
fi

exit
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序猿林仔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值