1.28笔记

文章目录

while 循环和 until 循环

while 循环语句

基本语法为:

bash 复制代码
while <条件表达式>
do
 指令...
done

如果该条件表达式成立,则执行while 循环体里的命令或语句(即语法中do和done之间的指令),每一次执行到done时就会重新判断while条件表达式是否成立,直到条件表达式不成立时才会跳出while 循环体。

示例:

1,初始资金1000,赚到10000000后躺平

bash 复制代码
#!/bin/bash
target=10000000
money=1000
while ((money<=target))
do
  echo -n "I'm working hard...Total:"
  sleep 0.5
  money=$[ money +1000000 ]
  echo $money
done

2,猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将第一天剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第 10 天早上想再吃时,发现只剩下一个桃子了。问原来有多少个桃子?

​ for循环语句示例:

bash 复制代码
#!/bin/bash
sum=1
for ((num=1;num<=9;num++))
do
  #let sum+=num
  sum=$[ (sum + 1)*2  ]
done
echo $sum

​ while循环语句示例:

bash 复制代码
#!/bin/bash
num=1
day=10
while ((day>1))
do
  num=$(((num+1)*2))
  day=$((day-1))
done
echo "原来桃子数量:$num"

3,每隔3秒监控一次sshd服务,如果sshd服务未运行,则启动服务。

bash 复制代码
#!/bin/bash
while ((1==1))
do
  if ! systemctl is-active sshd &>/dev/null;then
    systemctl start sshd && echo "$date Start sshd ..success"
  fi
  sleep 3
done

4,开发脚本:

  1. 随机产生一个50以内正整数,存放到/tmp/guess_number
  2. 提示用户输入一个50以内正整数
  3. 如果用户猜的数字大了,则提示用户猜大了,继续加油。继续提示用户输入一个50以内正整数。
  4. 如果用户猜的数字小了,则提示用户猜小了,继续加油。继续提示用户输入一个50以内正整数。
  5. 如果用户猜中数字,则提示用户:你好棒!退出脚本。
  6. 提示共计猜的次数。
bash 复制代码
#!/bin/bash
guess_result_file=/tmp/guess_number
# 生成一个小于50的正整数
num_real=$[ RANDOM%50+1 ]
echo $num_real > ${guess_result_file}
# 定义猜测次数变量
count=0
while true
do
  read -p "请输入一个50以内正整数:" num
  # 随着猜测次数增加
  let count++
  if (($num>50 || $num<1));then
    echo "错误"
  elif (($num==$num_real));then
    echo "第 $count 次猜测,你好棒!正确答案是 $num_real"
    exit
  elif (($num > $num_real));then
    echo "第 $count 次猜测:猜大了,继续加油"

  elif (($num < $num_real));then
    echo "第 $count 次猜测:猜小了,继续加油"
  fi
done

until 循环

基本语法

bash 复制代码
until <条件表达式>
do
 指令...
done

until 循环语句的用法与while 循环语句的用法类似,区别是until会在条件表达式不成立时,进入循环 执行指令;条件表达式成立时,终止循环

示例:

1,初始资金1000,赚到10000000后躺平

bash 复制代码
#!/bin/bash
target=10000000
money=1000
until ((money>=target))
do
  echo -n "I'm working hard...Total:"
  sleep 0.5
  money=$[ money +1000000 ]
  echo $money
done

shell脚本例题

1,开发脚本cpu_load.sh:消耗完系统所有cpu资源。

bash 复制代码
#!/bin/bash
cpu_count=$(lscpu |grep '^CPU(s):' | grep -o '[0-9]')
# 定义一个消耗系统所有cpu资源函数
function cpu_load (){
  sum=0
  while true
  do
    sum=$((1+1))
  done
}
# 产生和cpu数相同个数的进程
for ((num=1;num<=cpu_count;num++))
do
  cpu_load &
done

2,当进程被kill后再次生成

bash 复制代码
#!/bin/bash

cpu_count=$(lscpu |grep '^CPU(s):' | grep -o '[0-9]')

md5sum /dev/zero &

while true
do
  current_load=$(ps axo command,%cpu --sort -%cpu --no-header |grep -c md5sum)

  if ((current_load<cpu_count));then
    md5sum /dev/zero &
  fi

  sleep 1
done

shell三剑客

正则表达式

  • 正则表达式作为一个 pattern ,将 pattern 与要搜索的字符串进行匹配,以便查找一个或多个字符串。
  • 正则表达式,自成体系,由普通字符(例如字符 a 到 z)和元字符组成的文字模式。
    • 普通字符:没有显式指定为元字符的所有可打印和不可打印字符字符,包括所有大写和 小写字母、所有数字、所有标点符号和其他一些符号。
    • 元字符:出了普通字符之外的字符。 正则表达式,工具(vim、grep、less等)和程序语言(Perl、Python、C等)都使用正则表达式。

正则表达式分类:

  • 普通正则表达式
  • 扩展正则表示,支持更多的元字符

环境准备

bash 复制代码
[root@server ~ 15:01:52]# vim words
[root@server ~ 15:02:20]# cat words |grep 'cat'
cat
category
acat
concatenate
clt

普通字符

bash 复制代码
[root@server ~ 15:02:20]# cat words |grep 'cat'
cat
category
acat
concatenate
clt

字符集

[...]

匹配 [...] 中的任意一个字符。

bash 复制代码
[root@server ~ 15:02:59]# cat words |grep 'c[ab]t'
cat
category
acat
concatenate
cbt
[a-z] [A-Z] [0-9]
  • a-z\] ,匹配所有小写字母。

  • 0-9\] ,匹配所有数字。

[root@server ~ 15:03:19]# cat words |grep 'c[a-z]t'
cat
category
acat
concatenate
cbt
clt
[root@server ~ 15:03:31]# cat words |grep 'c[A-Z]t'
[root@server ~ 15:03:40]# echo cEt >> words
[root@server ~ 15:03:52]# cat words |grep 'c[A-Z]t'
cEt
[root@server ~ 15:03:53]# cat words |grep 'c[0-9]t'
c1t
[root@server ~ 15:04:00]# cat words |grep 'c[a-z0-9]t'
cat
category
acat
concatenate
c1t
cbt
clt
[root@server ~ 15:04:11]# cat words |grep 'c[a-zA-Z0-9]t'
cat
category
acat
concatenate
c1t
cbt
clt
cEt
[root@server ~ 15:04:20]# echo c-t >> words

要想匹配-符号,将改符号写在第一个位置

[root@server ~ 15:04:38]# cat words |grep 'c[-a-zA-Z0-9]t'
cat
category
acat
concatenate
c1t
cbt
clt
cEt
c-t

复制代码
##### \[\^...\]

匹配除了 \[...\] 中字符的所有字符。

```bash
[root@server ~ 15:04:50]# cat words |grep 'c[^ab]t'
c1t
clt
cEt
c-t
# ^放中间会被当做普通字符
[root@server ~ 15:05:10]# cat words |grep 'c[a^b]t'
cat
category
acat
concatenate
cbt
.

匹配除换行符( \n 、 \r )之外的任何单个字符,相等于 [^\n\r] 。

bash 复制代码
[root@server ~ 15:05:22]# cat words |grep 'c.t'
cat
category
acat
concatenate
c1t
cbt
clt
cEt
c-t
\

将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。 例如, 'n' 匹配字符 'n'。 \n 匹配换行符。序列 \ 匹配 \ ,而 ( 则匹配 ( 。

bash 复制代码
[root@server ~ 15:05:41]# echo c.t >> words 
[root@server ~ 15:06:00]# cat words |grep 'c\.t'
c.t
|

| 符号是扩展表达式中元字符,指明两项之间的一个选择。要匹配 | ,请使用\ | 。

bash 复制代码
# 使用egrep或者grep -E 匹配
[root@server ~ 15:06:06]# cat words |egrep 'cat|dog'
cat
category
acat
concatenate
dog
[root@server ~ 15:06:38]# cat words |grep -E 'cat|dog'
cat
category
acat
concatenate
dog
选项 描述
[[:digit:]] 数字: 0 1 2 3 4 5 6 7 8 9 等同于[0-9]
[[:xdigit:]] 十六进制数字: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f等同于[0-9a-fA-F]
[[:lower:]] 小写字母:在 C 语言环境和ASCII字符编码中,对应于[a-z]
[[:upper:]] 大写字母:在 C 语言环境和ASCII字符编码中,对应于[A-Z]
[[:alpha:]] 字母字符:[[:lower:]和[[:upper:]];在C语言环境和ASCII字符编码中,等同于**[A-Za-z]**
[[:alnum:]] 字母数字字符:[:alpha:]和[:digit:];在C语言环境和ASCII字符编码中,等同于**[0-9A-Za-z]**
[[:blank:]]或者[[:space:]] 空白字符:在 C 语言环境中,它对应于制表符、换行符、垂直制表符、换页符、回车符和空格。
[[:punct:]] 标点符号:在C语言环境和ASCII字符编码中,它对应于!" # $ % &'()*+,-./:;<=>?@[]^_`{|}~
[[:print:]]或者 [[:graph:]] 可打印字符: [[:alnum:]]、[[:punct:]]。
[[:cntrl:]] 控制字符。在 ASCII中, 这些字符对应八进制代码000到037和 177 (DEL)。

非打印字符

终端中不显示的字符,例如换行符。

字符 描述
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f 匹配一个换页符。等价于 \x0c\cL
\n 匹配一个换行符。等价于 \x0a\cJ
\r 匹配一个回车符。等价于 \x0d\cM
\s 匹配任何空白字符 ,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S 匹配任何非空白字符 。等价于 [^ \f\n\r\t\v]
\w 匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
\W 匹配任何非单词字符。等价于[^A-Za-z0-9_]
\t 匹配一个制表符。等价于 \x09\cI
\v 匹配一个垂直制表符。等价于 \x0b\cK

grep 命令支持\w\W\s\S

定位符

^

匹配行首位置。

bash 复制代码
[laoma@shell ~]$ cat words | grep '^cat'
cat
category

$

匹配行末位置。

bash 复制代码
[laoma@shell ~]$ cat words | grep 'cat$'
cat
acat

[laoma@shell ~]$ cat words | grep '^cat$'
cat

# 查询/etc/profile文件中有效行
[laoma@shell ~]$ cat /etc/profile | egrep -v '^#|^$'
# -v 取反,不显示匹配的内容

# 查看 /etc/ansible/ansible.cfg 中有哪些 section
[laoma@shell ~]$ cat /etc/ansible/ansible.cfg | egrep  '^\['

# 查看 /var/log/message Aug 19 14:01 到 Aug 19 14:06 时间段发生的事件
[laoma@shell ~]$ sudo cat /var/log/messages | egrep '^Aug 19 14:0[1-6]

\b

匹配一个单词边界。

bash 复制代码
[laoma@shell ~]$ echo hello cat >> words 
[laoma@shell ~]$ cat words | grep '\bcat'
cat
category
hello cat

[laoma@shell ~]$ cat words | grep 'cat\b'
cat
acat
hello cat

[laoma@shell ~]$ cat words | grep '\bcat\b'
cat
hello cat

\B

非单词边界匹配。

bash 复制代码
[laoma@shell ~]$ cat words | grep '\Bcat'
acat
concatenate

\< 和 \>

  • \< ,匹配一个单词左边界。
  • \>,匹配一个单词右边界。
bash 复制代码
[laoma@shell ~]$ cat words | grep '\<cat'
cat
category
hello cat

[laoma@shell ~]$ cat words | grep 'cat\>'
cat
acat
hello cat

限定次数

*

匹配前面的子表达式任意次数

bash 复制代码
[laoma@shell ~]$ echo dg >> words 
[laoma@shell ~]$ echo doog >> words 
[laoma@shell ~]$ cat words | grep 'do*g'
dog
dg
doog

+

+ 是扩展表达式元字符,匹配前面的子表达式一次以上次数

bash 复制代码
[laoma@shell ~]$ cat words | egrep 'do+g'
dog
doog

?

? 是扩展表达式元字符,匹配前面的子表达式一次以下次数

bash 复制代码
[laoma@shell ~]$ cat words | egrep 'do?g'
dog
dg

{n}

{} 是扩展表达式元字符,用于匹配特定次数。例如:{n},配置n次。

bash 复制代码
[laoma@shell ~]$ cat words | egrep 'do{2}g'
doog

{m,n}

{m,n},是扩展表达式元字符,用于匹配次数介于m-n之间。

bash 复制代码
[laoma@shell ~]$ echo dooog >> words
[laoma@shell ~]$ echo doooog >> words 

[laoma@shell ~]$ cat words | egrep 'do{2,3}g'
doog
dooog

{m,}

{m,},是扩展表达式元字符,匹配前面的子表达式m次以上次数

bash 复制代码
[laoma@shell ~]$ cat words | egrep 'do{2,}g'
doog
dooog
doooog

{,n}

{,n},是扩展表达式元字符,匹配前面的子表达式n次以下次数

bash 复制代码
[laoma@shell ~]$ cat words | egrep 'do{,3}g'
dog
doog
dg
dooog

()

标记一个子表达式。

bash 复制代码
[laoma@shell ~]$ echo dogdog >> words 
[laoma@shell ~]$ echo dogdogdog >> words 
[laoma@shell ~]$ echo dogdogdogdog >> words 

[laoma@shell ~]$ cat words | egrep '(dog){2,3}'
dogdog
dogdogdog
dogdogdogdog

[laoma@shell ~]$ cat words | egrep '(dog){2,}'
dogdog
dogdogdog
dogdogdogdog

综合案例

如何过滤出以下文件中所有有效IPv4地址?

bash 复制代码
0.0.0.0
1.1.1.1
11.11.11.111
111.111.111.111
999.9.9.9
01.1.1.1
10.0.0.0
0.1.1.1
266.1.1.1
248.1.1.1
256.1.1.1

具体步骤如下:

bash 复制代码
# 首先确定地址每位数范围
# 一位数,范围是 [0-9]
# 两位数,十位数 [1-9],个位数 [0-9]
# 三位数,1开头 1[0-9][0-9]
#        2开头 2[0-4][0-9]
#        25开头 25[0-5]
# 用 | 组合起来,三位数的要用()括起来当作一个整体:
([0-9]|[1-9][0-9]|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])
# 加上中间的 . 要使用转义符\
([0-9]|[1-9][0-9]|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))\.
# 重复三次
 (([0-9]|[1-9][0-9]|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))\.){3}
# 加上最后一位
 (([0-9]|[1-9][0-9]|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))\.){3}([0-9]|[1-9][0-9]|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))
# 测试 
[root@server ~ 15:56:11]# cat ip.list | egrep '^(([0-9]|[1-9][0-9]|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))\.){3}([0-9]|[1-9][0-9]|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))$'
0.0.0.0
1.1.1.1
11.11.11.111
111.111.111.111
10.0.0.0
0.1.1.1
248.1.1.1


# 优化整合
一位数和二位数
    [0-9]|[1-9][0-9]
=>  [1-9]?[0-9] 
三位数1开头
     1[0-9][0-9]
=>   1[0-9]{2}
# 得到
[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]     
# 最终结果
((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3})([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
# 测试
[root@server ~ 16:35:39]# cat ip.list | egrep '^((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3})([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
0.0.0.0
1.1.1.1
11.11.11.111
111.111.111.111
10.0.0.0
0.1.1.1
248.1.1.1
相关推荐
丝斯20112 小时前
AI学习笔记整理(63)——大模型对齐与强化学习
人工智能·笔记·学习
奔跑的web.7 小时前
TypeScript 装饰器入门核心用法
前端·javascript·vue.js·typescript
集成显卡7 小时前
Lucide Icons:一套现代、轻量且可定制的 SVG 图标库
前端·ui·图标库·lucide
pas1368 小时前
37-mini-vue 解析插值
前端·javascript·vue.js
十里-9 小时前
vue.js 2前端开发的项目通过electron打包成exe
前端·vue.js·electron
奥特曼_ it9 小时前
【数据分析+机器学习】基于机器学习的招聘数据分析可视化预测推荐系统(完整系统源码+数据库+开发笔记+详细部署教程)✅
笔记·数据挖掘·数据分析
雨季6669 小时前
构建 OpenHarmony 简易文字行数统计器:用字符串分割实现纯文本结构感知
开发语言·前端·javascript·flutter·ui·dart
小北方城市网10 小时前
Redis 分布式锁高可用实现:从原理到生产级落地
java·前端·javascript·spring boot·redis·分布式·wpf
console.log('npc')10 小时前
vue2 使用高德接口查询天气
前端·vue.js