九、shell 编程-数组
普通数组:只能用整数作为数组的索引 关联数组:可以使用字符串作为数组的索引
数组定义
普通数组定义: [root@newrain shell]# books=( linux shell awk sed ) 引用: [root@newrain shell]# echo ${books[0]} linux [root@newrain shell]# echo ${books[1]} shell [root@newrain shell]# echo ${books[2]} awk 关联数组需要提前声明 declare -A myarry1 [root@newrain shell]# declare -A myarry1 [root@newrain shell]# myarry1=([name]=newrain [sex]=man [age]=26) [root@newrain shell]# echo ${myarry1[name]} newrain [root@newrain shell]# echo ${myarry1[age]} 26
定义方法1: # declare -a myarry=(5 6 7 8) # echo ${myarry[2]} 显示结果为 7 定义方法2: # array=( one two three four five six ) # array2=(tom jack alice) # array3=(`cat /etc/passwd`) # array4=(tom jack alice "bash shell") # array5=(1 2 3 4 5 6 7 "linux shell" [20]=saltstack) 定义方法3: # 普通数组下标只能是数字 #!/bin/bash area[11]=23 area[13]=37 area[51]="UFOs"
访问数组
当设置任何数组变量时,可以访问它
[root@newrain shell]# aa=(haha heihei baibai) [root@newrain shell]# echo ${aa[0]} //访问数组中的第一个元素 [root@newrain shell]# echo ${aa[@]} //访问数组中所有的元素,等同与echo ${aa[*]} [root@newrain shell]# echo ${#aa[@]} //统计元素的个数 [root@newrain shell]# echo ${!aa[@]} //统计索引
${array_name[index]} //引用
示例
#!/bin/bash NAME[0]="BJ" NAME[1]="SH" NAME[2]="SZ" NAME[3]="GZ" NAME[4]="HZ" NAME[5]="ZZ" echo "First Index: ${NAME[0]}" echo "Second Index: ${NAME[1]}" echo "sixth Index: ${NAME[5]}"
输出结果为
$./test.sh First Index: BJ Second Index: SH sixth Index: ZZ
您可以访问数组中的所有项目通过以下方式之一:
${array_name[*]} ${array_name[@]}
示例
#!/bin/sh NAME[0]="BJ" NAME[1]="SH" NAME[2]="SZ" NAME[3]="GZ" NAME[4]="HZ" echo "First Index: ${NAME[*]}" echo "Second Index: ${NAME[@]}"
输出结果
$./test.sh First Index: BJ SH SZ GZ HZ Second Index: BJ SH SZ GZ HZ
疑难点 shell数组中"*" 和 "@" 区别
关于在shell脚本中数组变量中 “*”跟 “@” 区别 “*”当变量加上“” 会当成一串字符串处理. “@”变量加上“” 依然当做数组处理. 在没有加上“” 的情况下 效果是等效的.
示例
#!/usr/bin/env bash array=(gz cloud 19) echo "case 1" for line in "${array[@]}" do echo $line done echo "case 2" for line in "${array[*]}" do echo $line done echo "case 3" for line in ${array[*]} do echo $line done echo "case 4" for line in ${array[@]} do echo $line done
执行结果
case 1 gz cloud 19 case 2 gz cloud 19 case 3 gz cloud 19 case 4 gz cloud 19
遍历数组while [root@newrain array]# cat array01.sh #!/bin/bash #++ i 是先自加1后赋值;i ++ 是先赋值后自加1。 while read line do host[i++]=$line # 观察i++ 和 ++i的区别 done </etc/hosts for i in ${!host[@]} # 数组的元素索引 do echo "$i:${host[i]}" done 遍历数组for [root@newrain array]# cat array02.sh #!/bin/bash IFS='' for line in `cat /etc/hosts` # 读取文件中的每一行 do host[j++]=$line done for i in ${!host[@]} do echo ${host[i]} done 以上两个脚本都是读取文件中的行,然后加到一个数组中并进行遍历。 练习题:统计shell的种类和数量 思路:最后一列的sh种类不同,我们可以单独取出最后一列 /etc/passwd
十、正则表达式RE
正则表达式基本元字符
正则表达式拓展元字符
用来处理文本
正则表达式(Regular Expression, RE)是一种字符模式, 用于在查找过程中匹配指定的字符. 在大多数程序里, 正则表达式都被置于两个正斜杠之间;
例如/l[oO]ve/就是由正斜杠界定的正则表达式, 它将匹配被查找的行中任何位置出现的相同模式. 在正则表达式中,元 字符是最重要的概念
元字符使正则表达式具有处理能力。所谓元字符就是指ß那些在正则表达式中具有特殊意义的专用字符,可以用来规定 其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
No.1 正则表达式基本元字符
基本正则表达式元字符 元字符 示例 功能 ^ 行首定位符 ^love $ 行尾定位符 love$ . 匹配单个字符 l..e * 匹配前导符0到多次 ab*love .* 匹配任意多个字符 (贪婪匹配 [] 匹配方括号中任意一个字符 [lL]ove [ - ] 匹配指定范围内的一个字符 [a-z0-9]ove [^] 匹配不在指定组里的字符 [^a-z0-9]ove \ 用来转义元字符 love\. \n \< 词首定位符 #由数组或字母组成的 \<love \> 词尾定位符 love\> \(\) 匹配后的标签 # 在vim中测试
No.2正则表达式拓展元字符
= 等于 != 不等于 =~ 匹配 扩展正则表达式元字符 + 匹配一个或多个前导字符 [a-z]+ove ? 匹配零个或一个前导字符 lo?ve a|b 匹配a或b love|hate () 组字符loveable|rs love(able|rs) ov+ ov+ (ov)+ (..)(..)\1\2 标签匹配字符 # (love)able\1er x{m} 字符x重复m次 o{5} x{m,} 字符x重复至少m次 o{5,} x{m,n} 字符x重复m到n次 o{5,10}
十一、shell 编程-grep
egrep 支持正则表达式的拓展元字符 (或grep -E) #egrep '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' file1.txt
[root@newrain ~]# num1=1 1、运用正则,判断需要[[ ]] [root@newrain ~]# [[ $num1 =~ ^[0-9]+$ ]] && echo "yes" || echo "no" yes [root@newrain ~]# num3=1b1 [root@newrain ~]# [[ $num3 =~ ^[0-9]+$ ]] && echo "yes" || echo "no" no [root@newrain ~]# [[ $num =~ ^[0-9]+\.[0-9]+$ || $num =~ ^[0-9]+$ ]] && echo "yes" || echo "no" //输入的只能是数字(包括小数) 2、* 0或多个 [root@newrain ~]# useradd abrt [root@newrain ~]# grep 'abc*' /etc/passwd abrt:x:1041:1041::/home/abrt:/bin/bash 3、\< 词首定位符号 \>词尾定位符号 [root@newrain ~]# cat jack.txt Jack JACK JAck jackly :% s/\<[Jj]ack\>/123/g 4、^以什么开头 [root@newrain ~]# grep '^root' /etc/passwd root:x:0:0:root:/root:/bin/bash 5、$以什么结尾 [root@newrain ~]# grep 'bash$' /etc/passwd root:x:0:0:root:/root:/bin/bash confluence:x:1000:1000:Atlassian Confluence:/home/confluence:/bin/bash to:x:1003:1003::/home/to:/bin/bash 6、. 匹配单个字符 [root@newrain ~]# grep 'r..t' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin [root@newrain ~]# grep 'r.t' /etc/passwd operator:x:11:0:operator:/root:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 7、.* 任意多个字符 [root@newrain ~]# grep 'r.*t' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin polkitd:x:999:997:User for polkitd:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin abrt:x:1041:1041::/home/abrt:/bin/ 8、[] 匹配方括号中的任意一个字符 [root@newrain ~]# grep 'Root' /etc/passwd [root@newrain ~]# grep '[Rr]oot' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin 9、[ - ] 匹配指定范围内的一个字符 [root@newrain ~]# grep [a-z]oot /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin 10、[^] 匹配不在指定组内的字符,取反得意思 [root@newrain ~]# grep '[^0-9]oot' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin [root@newrain ~]# grep '[^0-9A-Z]oot' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin [root@newrain ~]# grep '[^0-9A-Za-z]oot' /etc/passwd [root@newrain ~]# [root@newrain ~]# useradd Root [root@newrain ~]# grep '[a-z]oot' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin Root:x:1042:1042::/home/Root:/bin/bash [root@newrain ~]# grep '^[rc]oot' /etc/passwd root:x:0:0:root:/root:/bin/bash ^在[]内表示取反,^在[]外表示以什么开头 11、\(\)匹配后的标签 [root@newrain ~]# cat file1.txt IPADDR=192.168.1.123 GATEWAY=192.168.1.1 NETMASK=255.255.255.0 DNS=114.114.114.114 :% s#\(192.168.1.\)123#\12# :% s#\(192.\)\(168.\)\(1.\)2#\1\2\35# :% s\(192.\)\(168.\)\(1.\)\(5\)#\1\26.\4# 扩展正则表达式元字符 + 匹配一个或多个前导字符 [a-z]+ove ? 匹配零个或一个前导字符 lo?ve a|b 匹配a或b love|hate (..)(..)\1\2 标签匹配字符 (love)able\1er x{m} 字符x重复m次 o{5 x{m,} 字符x重复至少m次 o{5,} x{m,n} 字符x重复m到n次 o{5,10} 1、+ 匹配一个或多个前导字符 [root@newrain ~]# egrep 'ro+t' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin 2、? 匹配零个或一个前导字符 [root@newrain ~]# egrep 'ro?t' /etc/passwd abrt:x:1041:1041::/home/abrt:/bin/bash 3、a|b 匹配a或b [root@newrain ~]# netstat -anlp|egrep ':80|:22' [root@newrain ~]# egrep 'root|alice' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin 4、x{m} 字符x重复m次 [root@newrain ~]# cat a.txt love love. loove looooove [root@newrain ~]# egrep 'o{2}' a.txt loove looooove [root@newrain ~]# egrep 'o{2,}' a.txt loove looooove [root@newrain ~]# egrep 'o{6,7}' a.txt
扩展
.*: 贪婪匹配
grep是过滤一行
-z 变成一行
美化脚本(31、32、33)红绿黄
echo -e "\e[032m[软件包安装] $line\e[0m"
[root@localhost xa_day3]# echo -e "\e[031m[我爱你] $line\e[0m"
周六
远程调用变量,这样写