34、shell数组+正则表达式

0、课前补充

less 复制代码
jiafa () {
result=$(echo " $1 + $2 " | bc )
print "%.2f\n" "$result"
}                   ##保留小数点两位 

薄弱加强点

复制代码
a=$(df -h | awk 'NR>1 {print $5}' | tr -d '%')
echo "$a"

一、数组

1.1、定义

数组的定义:在集合种指定多个元素。

1.2、元素类型

元素的类型:整数,字符串,可以是浮点。

1.3、数组的作用

数组的作用:一次性的定义多个元素,可以为变量赋值提供便利。

1.4、数组的定义方法:

1.4.1、数组的格式

数组名= (a b c d)

数组名不能重复

复制代码
[root@test1 opt]# vim test56.sh 
[root@test1 opt]# test1=(a b c d)
[root@test1 opt]# echo ${test1[*]}
a b c d
[root@test1 opt]# echo ${test1[@]}
a b c d

[root@test1 opt]# test2[0]=1
[root@test1 opt]# test2[1]=2
[root@test1 opt]# test2[2]=3
[root@test1 opt]# echo ${test2[@]}
1 2 3

1.4.2、数组的长度

#数组的长度指的是:数组内包含了几个元素。

打印出数组的长度:

复制代码
echo ${#数组名[*]} 

例子:

复制代码
echo ${#test[*]}  ##打印数组内包含了几个元素

[root@test1 opt]# echo ${#test1[*]}
4
[root@test1 opt]# echo ${#test2[*]}
3

1.4.3、查看数组指定位置元素---开始为0

复制代码
echo ${数组名[下标]}

例子:

复制代码
[root@test1 opt]# test3=(abc 123 456 789 dahanqi)
[root@test1 opt]# echo ${test3[0]}
abc
[root@test1 opt]# echo ${test3[2]}
456
[root@test1 opt]# echo ${test3[3]}
789

1.4.4、数组遍历

复制代码
[root@test1 opt]# vim shuzu.sh

#数组遍历
test=(1 2 3 4 5)
for num in ${test[*]}
do
echo -ne "$num\t"
done



[root@test1 opt]# sh shuzu.sh
1	2	3	4	5	

1.4.5、数组的切片

复制代码
echo ${数组名[*]:下标:打印长度}

例子:

复制代码
[root@test1 opt]# test5=(1 2 3 4 5)
[root@test1 opt]# echo ${test5[*]}
1 2 3 4 5
[root@test1 opt]# echo ${test5[*]:0:2}
1 2

#0表示起始位置,2表示步长,起始位置θ开始,包括0,移2个。

复制代码
[root@test1 opt]# echo ${test5[*]:1:3}
2 3 4

1.4.6、数组的替换

#临时替换

复制代码
echo ${数组名[*]/下标/数值}

例子:

复制代码
[root@test1 opt]# echo ${test5[*]/4/99}
1 2 3 99 5    ##临时替换

#永久修改

通过修改元素下标的值可以实现----赋值覆盖。

复制代码
[root@test1 opt]# echo ${test5[*]}
1 2 3 4 5
[root@test1 opt]# echo ${test5[*]/4/99}
1 2 3 99 5    ##临时替换
[root@test1 opt]# echo ${test5[*]}
1 2 3 4 5
[root@test1 opt]# test5[3]=99  ##重新赋值覆盖替换
[root@test1 opt]# echo ${test5[*]}
1 2 3 99 5

1.4.7、删除数组

#删除整个数组

复制代码
unset 数组名

例子:

复制代码
[root@test1 opt]# echo ${test1[*]}
a b c d
[root@test1 opt]# unset test1
[root@test1 opt]# echo ${test1[*]}

[root@test1 opt]# echo ${test1[*]}

[root@test1 opt]#

1.4.8、删除元素

#删除数组当中的元素---通过单个下标删除

复制代码
unset 数组名[下标]

例子:

复制代码
[root@test1 opt]# echo ${test5[*]}
1 2 3 99 5
[root@test1 opt]# unset test5[2]
[root@test1 opt]# echo ${test5[*]}
1 2 99 5
[root@test1 opt]# echo ${test5[3]}
99
[root@test1 opt]# echo ${test5[2]}

1.4.9、数组追加,追加元素

复制代码
数组名[下标]=数值

根据下标追加

复制代码
[root@test1 opt]# test5[4]=5
[root@test1 opt]# echo ${test5[*]}
1 2 3 99 5
[root@test1 opt]# test5[5]=6
[root@test1 opt]# echo ${test5[*]}
1 2 3 99 5 6

在尾部追加

复制代码
数组名+=(x  y)

例子:

复制代码
[root@test1 opt]# test5+=(7 8)
[root@test1 opt]# echo ${test5[*]}
1 2 3 99 5 6 7 8

#现在定义一个数组,元素都是整数,实现数组内整数的累加求和

复制代码
test1=(10 20 30 40 50 60)
b=0
for ((i=0;i<6;i++))
do
a=`echo ${test1[i]}`
b=$(($a+$b))
done
echo $b

[root@test1 opt]# vim shuzu1.sh
[root@test1 opt]# sh shuzu1.sh
210
复制代码
[root@test1 opt]# vim shuzu1.sh



test1=(10 43 45 47 50 60)
sum1=0
sum2=0
for i in ${test1[*]}
do
if [[ $i%2 -eq 0 ]]
then
sum1=$(($sum1+$i))
else
sum2=$(($sum2+$i))
fi
done
echo $sum1
echo $sum2



[root@test1 opt]# sh shuzu1.sh
120
135
复制代码
root@test1 opt]# vim shuzu2.sh

test1=(3 5 8 4 56 34 76 53)
max=${test1[0]}
min=${test1[0]}
for i in ${test1[*]}
do
 if [ $i -gt $max ]
  then         
  max=$i           ##取数组里面大于的话,赋值给max,小于等于不用管
  fi
 if [ $i -lt $min ]
 then
  min=$i              ##取数组里面小于的话,赋值给min,大于等于不用管
  fi
done
echo "$max"
echo "$min"



[root@test1 opt]# sh shuzu2.sh
76
3

1.5、冒泡排序

复制代码
#冒泡排序:#类似气泡上涌的工作,会将数组当中的元素按照从小到大,或>者从大道小的顺序进行一个重新排列。test1=(20 10 60 40 50 30)
#从小到大排列。
#思路:对比两个相邻的元素,以从小到大为例。满足交换条件的元素,小的
往左移,大的往右移动。
#数组的位置发生变化(下标对应的元素的值发生变化)
#双层循环,外部循环控制排序的轮次。内循环比较两个元素的大小,决定>时候互换位置
#对比和交换的次数随着排序轮次而减少


[root@test1 opt]# vim shuzu3.sh
test1=(20 10 60 40 50 30)
length=${#test1[*]}
for ((b=1;b<length;b++))
do
for ((a=0;a<=length-b;a++))
do
  c=${test1[$a]}
  d=${test1[(($a+1))]}
  if [ $c -gt $d ]
  then
   e=$c
   test1[$a]=$d
   test1[(($a+1))]=$c
fi
done
done
echo "${test1[*]}"



[root@test1 opt]# sh shuzu3.sh
10 20 30 40 50 60

总结:取最大值,内循环,第一次循环需要,length-1次内循环,最大值在最后,a++后,b++,外循环第二次,这时候最大值已经在最后一位,那么内循环此时需要进行length-2次,依次类推

详见下:

复制代码
  [root@test1 opt]# bash -x shuzu3.sh

  + test1=(20 10 60 40 50 30)
  + length=6
  + (( b=1 ))
  + (( b<length ))
  + (( a=0 ))
  + (( a<length-b ))
  + c=20
  + d=10
  + [[ 20 -gt 10 ]]
  + e=20
  + test1[$a]=10
  + test1[(($a+1))]=20
  + (( a++ ))
  + (( a<length-b ))
  + c=20
  + d=60
  + [[ 20 -gt 60 ]]
  + (( a++ ))
  + (( a<length-b ))
  + c=60
  + d=40
  + [[ 60 -gt 40 ]]
  + e=60
  + test1[$a]=40
  + test1[(($a+1))]=60
  + (( a++ ))
  + (( a<length-b ))
  + c=60
  + d=50
  + [[ 60 -gt 50 ]]
  + e=60
  + test1[$a]=50
  + test1[(($a+1))]=60
  + (( a++ ))
  + (( a<length-b ))
  + c=60
  + d=30
  + [[ 60 -gt 30 ]]
  + e=60
  + test1[$a]=30
  + test1[(($a+1))]=60
  + (( a++ ))
  + (( a<length-b ))
  + (( b++ ))
  + (( b<length ))
  + (( a=0 ))
  + (( a<length-b ))
  + c=10
  + d=20
  + [[ 10 -gt 20 ]]
  + (( a++ ))
  + (( a<length-b ))
  + c=20
  + d=40
  + [[ 20 -gt 40 ]]
  + (( a++ ))
  + (( a<length-b ))
  + c=40
  + d=50
  + [[ 40 -gt 50 ]]
  + (( a++ ))
  + (( a<length-b ))
  + c=50
  + d=30
  + [[ 50 -gt 30 ]]
  + e=50
  + test1[$a]=30
  + test1[(($a+1))]=50
  + (( a++ ))
  + (( a<length-b ))
  + (( b++ ))
  + (( b<length ))
  + (( a=0 ))
  + (( a<length-b ))
  + c=10
  + d=20
  + [[ 10 -gt 20 ]]
  + (( a++ ))
  + (( a<length-b ))
  + c=20
  + d=40
  + [[ 20 -gt 40 ]]
  + (( a++ ))
  + (( a<length-b ))
  + c=40
  + d=30
  + [[ 40 -gt 30 ]]
  + e=40
  + test1[$a]=30
  + test1[(($a+1))]=40
  + (( a++ ))
  + (( a<length-b ))
  + (( b++ ))
  + (( b<length ))
  + (( a=0 ))
  + (( a<length-b ))
  + c=10
  + d=20
  + [[ 10 -gt 20 ]]
  + (( a++ ))
  + (( a<length-b ))
  + c=20
  + d=30
  + [[ 20 -gt 30 ]]
  + (( a++ ))
  + (( a<length-b ))
  + (( b++ ))
  + (( b<length ))
  + (( a=0 ))
  + (( a<length-b ))
  + c=10
  + d=20
  + [[ 10 -gt 20 ]]
  + (( a++ ))
  + (( a<length-b ))
  + (( b++ ))
  + (( b<length ))
  + echo '10 20 30 40 50 60'
    10 20 30 40 50 60

二、正则表达式

正则表达式:匹配的是文本内容,linux的文本三剑客都是针对文本内容。

grep 过滤文本内容

sed 针对文本内容进行增删改查

awk 按行取列

文本三剑客----都是按照行进行匹配。

2.1、grep筛选:

grep的作用就是使用正则表达式来匹配文本内容。

选项:

-m 数字 匹配几次之后停止

复制代码
[root@test1 opt]# grep -m 1 root /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@test1 opt]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

-v 取反

复制代码
grep -v root /etc/passwd   ##除了root,筛选所有

-n 显示匹配的内容及行号

复制代码
[root@test1 opt]# grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

-c 只统计匹配的行数

复制代码
[root@test1 opt]# grep -c root /etc/passwd 
2

-o 仅显示匹配的结果

复制代码
[root@test1 opt]# grep -o root /etc/passwd 
root
root
root
root

-q 静默模式。不输出任何信息。

复制代码
[root@test1 opt]# grep -q root /etc/passwd > /opt/123.txt
[root@test1 opt]# cat /opt/123.txt
[root@test1 opt]# grep -m 1 root /etc/passwd > /opt/123.txt
[root@test1 opt]# cat /opt/123.txt
root:x:0:0:root:/root:/bin/bash

-A after 数字,后几行

复制代码
grep -A 3 root /etc/passwd

-B before 数字 ,前几行

复制代码
grep -B 3 root /etc/passwd

-C 数字,前后各几行

复制代码
grep -C 3 root /etc/passwd

-e 或者

复制代码
 grep -e root -e xy102 /etc/passwd

-E 匹配扩展正则表达式

-f 匹配两个文件相同的内容,以第一个文件为准

复制代码
[root@test1 opt]# vim kl1.txt
abc
acv
abf123
234
456
aaa
bbb
ccc
abc
acv
abf123
234
456
aaa
bbb
ccc
abc
acv
abf


[root@test1 opt]# vim kl1.txt

123
345
qqq
aaa
abf
avg
afh


[root@test1 opt]# grep -f kl.txt kl1.txt
123
aaa
abf

-r 递归目录 目录下的文件内容,软连接不包含在内。

复制代码
[root@test1 opt]# grep -r 123 /opt/
/opt/test41.sh:  echo 123 | passwd --stdin $user
/opt/test41.sh:  echo 123 | passwd --stdin $user
匹配到二进制文件 /opt/.123.swp

-R 递归目录 目录下的文件内容,软连接包含在内。

复制代码
[root@test1 opt]# grep -R abf /opt/
/opt/nginx-1.22.0/src/core/ngx_crc32.c:    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
/opt/999.txt:abf123

2.2、sort排序:

sort

以行为单位,对文件的内容进行排序

sort 选项 参数

复制代码
[root@test1 opt]# sort 123.txt





111
112
123
222
333
555
aaa
aaa
aaa
bbb
bbb
cc
ddd
DDD
EEE
nnn

cat file | sort 选项

-f 忽略大小写,默认会把大写字母排在前面

复制代码
[root@test1 opt]# sort -f 123.txt





111
112
123
222
333
555
aaa
aaa
aaa
bbb
bbb
cc
DDD
ddd
EEE
nnn

-b 忽略每行之前的空格(不是把空格删除,只是按照数字和字母的顺序排列)

复制代码
[root@test1 opt]# sort -b 123.txt




​	
 123
345
345
 345
567
987
aaa
bbb
bbb
BD
bfvf
SD
sdfd
sds

-n 按照数字进行排序

复制代码
[root@test1 opt]# sort -n 123.txt




​	
aaa
bbb
bbb
BD
bfvf
SD
sdfd
sds
 123
345
345
 345
567
987

-r 反向排序

复制代码
[root@test1 opt]# sort -r 123.txt
sds
sdfd
SD
bfvf
BD
bbb
bbb
aaa
987
567
 345
345
345
 123

-u 相同的数据只显示一行

复制代码
[root@test1 opt]# sort -u 123.txt

	
 123
345
 345
567
987
aaa
bbb
BD
bfvf
SD
sdfd
sds

-o 把排序后结果转存到指定的文件

复制代码
[root@test1 opt]# sort -u 123.txt


 123
345
 345
567
987
aaa
bbb
BD
bfvf
SD
sdfd
sds
[root@test1 opt]# cat 123.txt | sort -rno 234.txt
[root@test1 opt]# cat 234.txt
987
567
 345
345
345
 123
sds
sdfd
SD
bfvf
BD
bbb
bbb
aaa

2.3、uniq 去重

uniq 去除连续重复的行,只显示一行

-c 统计连续行的次数,合并连续重复的行

复制代码
[root@test1 opt]# uniq -c 123.txt
      1  345
      1 567
      1 987
      1  123
      2 345
      1 bbb
      1 bfvf
      2 
      1 sdfd
      1 SD
      1 BD
      2 
      1 	
      1 sds
      2 aaa
      1 bbb

-u 显示仅出现一次的行(包括不适合连续出现的重复行)

复制代码
[root@test1 opt]# uniq -u 123.txt
 345
567
987
 123
bbb
bfvf
sdfd
SD
BD
	
sds
bbb

-d 仅显示连续重复的行(不包括非连续出现的内容)

复制代码
[root@test1 opt]# uniq -d 123.txt   ##显示重复的行
345                          


aaa

作业

复制代码
[root@test1 ~]# df -h | awk 'NR>1 {print  $5}' | tr -d '%'
15
0
0
1
0
100
18
1
0
1

#按照从大到小排列

#附加题从小到大,整行排序

复制代码
test1=($(df -h | awk 'NR>1 {print $5}' | tr -d '%'))
echo "原数组的排序为:${test1[*]}"
length=${#test1[*]}
for ((j=1;j<$length;j++))
do
 for ((k=0;k<$length-j;k++))
 do
  a=${test1[$k]}
  b=${test1[$(($k+1))]}
  if [ $a -lt $b ]
   then
    c=$b
    test1[$k]=$c
    test1[$(($k+1))]=$a
    fi
done
done
echo "数组从大到小的排序为:${test1[*]}"
df -h | awk 'NR>1 {print $0, $5}' | sort -k5  -nr
相关推荐
醉方休22 分钟前
Node.js 精选:50 款文件处理与开发环境工具库
linux·运维·node.js
代码老y2 小时前
从裸机到云原生:Linux 操作系统实战进阶的“四维跃迁”
linux·运维·云原生
CMCST2 小时前
CentOS 7.9 升级 GLibc 2.34
linux·运维·centos
xiep14383335102 小时前
Rocky Linux 10 部署 Kafka 集群
linux·运维·kafka
笨鸟要努力6 小时前
Ubuntu 全盘备份
linux·运维·ubuntu
ChironW6 小时前
Ubuntu 22.04 离线环境下完整安装 Anaconda、CUDA 12.1、NVIDIA 驱动及 cuDNN 8.9.3 教程
linux·运维·人工智能·深度学习·yolo·ubuntu
大飞pkz6 小时前
【C#】正则表达式
开发语言·正则表达式·c#·string·字符串匹配·高效字符串匹配
轻松Ai享生活7 小时前
linux 日志详解
linux
小白的代码日记7 小时前
Linux常用指令
linux·运维·服务器
月舞之剑8 小时前
linux离线安装nodejs
linux·node.js