Shell
更新时间:2023-11-27 10:05:40
一、正则表达式
# 通配符
任意长度任意字符,属于通配符
? 单个任意字符,属于通配符
# 基础正则表达式
\ 转义符
^ 匹配行首
$ 匹配行尾
^$ 表示空行
. 匹配除换行符\n之外的任意单个字符
.* 匹配任意长度任意字符
[] 匹配包含在[字符]之中的任意一个字符
[^] 匹配[^字符]之 外的任意一个字符
^[^字符] 匹配非 指定字符开头的行
\{n\} 匹配之前的项n次,n是可以为0的正整数
\{n,\} 之前的项至少需要匹配n次
\{n,m\} 指定之前的项至少匹配n次,最多匹配m次
# 转义符
\a 响铃
\b 退格
\n 换行
\r 替换字符
\t 空一个tab键位置
\v 制表符
\\\ 代表一个反斜杠字符
二、脚本’三剑客’
# grep
$ grep 参数 '关键字' 文件名
参数
-i 忽略大小写
-v 显示没有被模式匹配到的行,相当于^[^]
-o 只显示被模式匹配到的字符串
-n 显示匹配行及行号
-c 只输出匹配行的计数
-l 查询多文件时只输出包含匹配字符的文件名
-L 打印不匹配的文件名
-e 满足多个过滤参数的条件
-r 递归查询
-E 使用扩展的正则表达式
-w 只显示全单词符合的行
-q 匹配内容不显示(静默模式)
$ sed 选项 '行定界 /old字符/new字符/ 列定界符 处理动作' 文件名
定界符
s 替换指定的字符
g 全局替换
i 不区分字符大小写
选项
-i 直接编辑原文件
-e 'script' -e 'script': 指定多个编辑指令
-n 静默模式(默认打印),或只显示匹配后的内容
处理动作:
! 取反,如!W、!=、!d、!i\#、!r \#、!w \#
d 删除
c 取代,c后面可以接字串,这些字串可以取代n1,n2之间的行
p 打印,通常p会与参数-n- -起
i或i\ : 在被指定到行的上面插入文本
a或a \ : 在被指定的行的下面插入文本
\n: 换行
r 文件:在指定位置把另外-个文件的内容插入
w 文件:将符合条件的所有行保存至指定文件中
= 显示符合条件的行的行号
$ awk 选项 '模式或条件(编辑命令)' 文件
# awk的常用的内置变量
FILENAME awk 读取的文件名
FNR 浏览文件的记录数(浏览文件次数,文件会累加记录)
NF 浏览记录的域个数(当前行的字段数)
$NF 表示最后一个区域
NR 已读的记录行数(命令后跟的所有文件统一合并计数)
三、例子
# grep
grep -i '关键字' 文本名称 # 忽略大小写过滤关键字
grep -v '关键字' 文本名称 # 过滤非关键字的行
grep -o '关键字' 文本名称 # 只显示被匹配到的字符
grep -n '关键字' 文本名称 # 过滤关键字,并带行号打印
grep -e '关键字1' -e '关键字2' 文本名称 # 过滤关键字1并且过滤关键字2
grep -l '关键字' 文本名称1 文本名称2 # 过滤关键字存在的文件名
grep -L '关键字' 文本名称1 文本名称2 # 过滤关键字不存在的文件名
grep -w '关键字' 文本名称 # 以单词形式过滤
grep -q '关键字' 文本名称 # 静默模式,不输出任何信息
grep '关键字' 文本名称 # 过滤带有关键字的行
grep '^关键字' 文本名称 # 过滤以关键字开头的行
grep '关键字$' 文本名称 # 过滤以关键字结尾的行
grep '^a..b' 文本名称 # 过滤以a开头中间两个任意字符b结尾的行
grep 'a*' 文本名称 # 过滤以a开头后面跟着任意长度的任意字符的行
grep -c '^$' 文本名称 # 过滤空行
# sed
sed 's/aaa/bbb/' 文本名称 # 全文首匹配替换
sed 's/aaa/bbb/g' 文本名称 # 全文匹配替换
sed 's/aaa//g' 文本名称 # 全文匹配替换为空
sed '2 s/aaa/bbb/' 文本名称 # 第二行单行首匹配替换
sed '2 s/aaa/bbb/g' 文本名称# 第二行单行全行替换
sed 's/^/aaa/g' 文本名称 # 全行首插入
sed 's/aaa/bbb/2' 文本名称 # 每行第二次匹配到的替换
sed '2 s/aaa/bbb/2' 文本名称# 第二行第二次匹配到的替换
sed 'G' 文本名称 # 在文件的每行后添加空行
sed '1c aaa' 文本名称 # 整行低缓,把第一行替换成aaa
sed '1,3c aaa' 文本名称 # 把第一行到第三行替换成一行aaa
sed -n '2p' 文本名称 # 只显示第二行
sed -n '1,2p' 文本名称 # 只显示第一行到第二行
sed '2q' 文本名称 # 只打印前两行
sed -n '/ftp/p' 文本名称 # 只打印带有ftp字符的行
sed -n '$p' 文本名称 # 只打印最后一行
sed -n '2,$p' 文本名称 # 只打印第二行到最后一行
sed -n '1p;$p' 文本名称 # 只打印第一行到最后一行
sed '2d' 文本名称 # 删除第二行
sed '$d' 文本名称 # 删除最后一行
sed '1,3d' 文本名称 # 删除第一行到第三行
sed '/^\$/d' 文本名称 # 删除以$字符开头的行
sed '$!d' 文本名称 # 删除除了最后一行外的其他行
sed '/^$/d' 文本名称 # 删除空行
sed '/aaa$/d' 文本名称 # 删除以aaa结尾的行
# awk
awk 'NR==1{print}' 文本名称 # 打印文件第一行
awk -F ':' '{print $1}' 文本名称 # 以:为分隔符,只打印整个文件第一列
awk -F':’ {print $3}' 文本名称 # 以:为分隔符,只打印文件第三列
awk '{print}' 文本名称 # 以默认分隔符(空格分割符),打印整个文件($0表示整个文件列)
awk '{print}' < 文本名称
cat 文本名称 |awk '{print}'
awk '{print $0}' 文本名称
awk '/root/' 文本名称 # 以:号为分割符,匹配打印带有root字符的行(/字符/字符匹配)
awk -F':' '/^root/' 文本名称 # 以:号为分割符,打印开头是root字符的行
awk -F':' '/^\<root\>/' 文本名称
awk -F':' '/^(root|ftp)/{print $1,$7}' 文本名称 # 以:号为分割符,打印开头是root字符或者ftp字符的行的第一列和第七列字符
awk -F':' '!/^root/' 文本名称 # 以:号为分割符,打印开头非root字符的行,!取反的意思
awk '/^$/' 文本名称 # 打印文件中空行
awk '/2019$/' 文本名称 # 以:空格为分隔符,打印结尾为2019的行
awk '/^[Rr]oot/' 文本名称 # 以默认空格分割符,打印Root或root开头的行
ifconfig ens32|awk '/<inet\>/{print $2}'# 过滤网卡IP
# 条件操作描述符
关系操作符>、 >=、<、 <=、==(精确匹配)、!=(不等于)
赋值操作符=、+=、*=、/=、%=、^=
# 条件表达操作符
或||、与&&、非!
匹配操作符-(模式匹配,模糊匹配) !~
算术操作符+、-、*、/、%、^(次方)
四、shell 条件测试
# 条件测试
#测试特定的条件是否成立当条件成立则返回0,否则返回其他数值根据命令的执行返回值来判断
0 真 执行成功True
非0 假 执行失败False
# test命令测试形式
test 条件表达式
# 常见的条件测试
文件测试
-d 判断是否为目录
-f 判断是否为文件
-r 判断当前用户是否有读取权限
-W 判断当前用户是否有写入权限
-x 判断当前文件是否有执行权限
-e/a 判断目录或文件是否存在
# 例子
test -d /etc/passwd
echo $?
[ -d /etc/ ]
echo $?
[ -f /opt/abc.txt ] || touch /opt/abc.txt
echo $?返回值为0表示命令正确,否则失败
# 整数比较
给定两个整数,判断第一个数是否大于,小于,等于第二个数
-eq 表示等于
-ne 表示不等于
-gt 表示大于
-lt 表示小于
-le 表示小于等于,满足其中任意一个条件即为真
-ge 表示大于等于,满足其中任意-个条件即为真
# 字符串比较
检查用户输入的字符串是否符合需求
== 表示第一个字符串和第二个字符串相同
!= 第一个字符串和第二个字符中不同(!取反的意思)
-z 字符串:字符串是否为空,不空则假,空则为真
[-n字符串]]: 字符串是否为空,不空则真,空则为假
# 例子
abc=www
[ -Z $abc ] && echo "$abc"
[[ -n $www ]lecho $?
a=root
b=ftp
["$a" == "$b" ]:echo $?
["$a"!= "$b" ]:echo $?
a="root"
b="root"
["$a" == "$b" ]:echo $?
# 多个条件的逻辑测试
测试两个或多个条件之间的依赖关系
&&/-a 逻辑与:并且的意思,两边的条件都满足才执行下一步
0&& 0=0
0&& 1=1
1 && 0=1
1 && 1=1
# 例子
[1 -eq1]&&[2 -gt 1] && echo "执行正确"
1=1并且2>1,打印”执行正确”
[1 -eq1]&&[2 -It 1] && echo "执行正确"
1=1并且2不小于1,不打印"执行正确”
[1 -eq1 -a2 -ne 1]&& echo "执行正确”
|/-o逻辑或:或者的意思,两边的条件只要有一个满足就执行下一步
0||0=0
0||0=0
1||0=0
1||1=1
[1 -eq 1]||[2 -lt 1]&& echo "执行正确"
[1 -eq 1 -o 2 -lt 1]&& echo "执行正确"
1=1或者2小于1,打印”执行正确”
# !逻辑否(非),!写在[ ]里外都可以
取反的意思,满足前提条件,则不执行下一步,不满足前提条件执行下一步操作
[1 -eq 1 ];echo $?
![1 -eq 1 ];echo $?
[!1 -eq 1 ];echo $?
五、shell if语句类型
# 单分支
if [条件测试语句]
then
命令序列
fi
# 双分支
if [条件测试语句]
then
命令序列1
else
命令序列2
fi
# 多分支
if [条件测试语句1 ]
then
命令序列1
elif [条件测试语句2 ]
then
命令序列2
else
命令序列3
fi
六、shell for语句类型
for 变量名 in 取值列表
do
命令序列(循环体)
done
例子
打印1到10
for i in seq `1 10`
do
echo $i
done
# 批量创建以test开头的用,创建10个,初始密码设置123456
for i in test{1..10}
do
useradd $i
echo "123456"lpasswd --stdin $i &> /dev/nul
done
# 根据文件批量检测多台主机的存活状态
IP= $(cat /root/ip.txt)
for i in $IP
do
ping -c2 -i0.2 -W3 $i &> /dev/null
if[$? -eq 0 ]
then
echo "Host $i is up"
else
echo "Host $i is down"
fi
done
# 查看多台主机的多个端口是否开启(前提主机之间秘钥互信)
for in 128 129
do
for p in 222325
do
ssh 192.168.80.$i netstat -anptu|grep -q "$p" && echo "port $p is up"
done
done
七、shell while语句类型
while [条件表达式]
do
命令序列
done
# 特殊的条件测试
true 真条件永远成立,无限循环,除非强制终止。
while true.
do.
echo”123”。
done。
# 例子
计算1到100的和
a= 1
sum=0
while [ $a -le 100 ]
do
sum=' expr $sum + $a^
a='expr$a+1
done
echo $sum
八、shell case语句类型
case 变量值 in
模式1)
命令序列 1
;;
模式2)
命令序列 2
;;
*)
默认命令序列
;;
esac
# 例子
提示用户输入一个字符判断出该字符是字母,数字或者其他字符
read -p "输入一个字符” key
case $key in
[a-z][A-Z])
echo "字母"
;;
[0-9])
echo "数字”
;;
*)
echo "其他字符"
esac
sleep 1 控制脚本的循环速度(睡眠1s)
seq 起始值 步长 结束值
shell 循环控制结构
break 语句可以结束while,for,until或者select等结构的执行,退出循环体
continue 跳出本次循环,回到循环的开始位置,继续执行下次循环。
exit 退出脚本,循环体外的命令不会执行。