一、字符串处理
{变量:开始位置:长度}</span></strong></p><p><span style="color:#3f3f3f;"><strong>{变量/旧/新}
{变量##*:}</span><br></strong></span></p><p><span style="color:#3f3f3f;"><strong><span style="color:rgb(63,63,63);"><span style="color:rgb(63,63,63);">{变量%%:*}
{变量:-111}</span><br></span></span></span></span></p><p><strong><span style="color:rgb(63,63,63);">1.字符串截取及切割</span></strong></p><p>1)子串截取</p><p>子串截取的三种用法:</p><p> 应用:隐藏身份证后<span style="font-family:Calibri;">6</span><span style="font-family:'宋体';">位;做验证码</span><span style="font-family:Calibri;">a=’0123456789‘ </span><span style="font-family:'宋体';">随机截取四位数字;给电脑配随机密码,每次取四位,用</span><span style="font-family:Calibri;">for</span><span style="font-family:'宋体';">循环;</span></p><p>(<span style="font-family:Calibri;">1</span><span style="font-family:'宋体';">)</span><strong><span style="font-family:System;">{phone:起始位置:长度} (从0开始计位数)
#phone=’15170016044’ 要求提取7001
#echo{phone:0:4} = echo{phone::4} / 起始位置为0可以省略
# echo{<span style="color:rgb(128,0,0);">#</span>phone} <span style="font-family:'宋体';">显示</span><span style="font-family:Calibri;">11 /</span><span style="font-family:'宋体';">加</span><span style="font-family:Calibri;">#</span><span style="font-family:'宋体';">号统计这个变量有多少位</span></p><p> #echo{phone:3:4} 显示 7001 /从第几位开始截几位
(2)expr substr ”</span>phone" <span style="font-family:'宋体';">起始位置 </span><span style="color:rgb(128,0,0);">长度</span></span> </strong><span style="color:rgb(128,0,0);">(从<span style="font-family:Calibri;">1</span><span style="font-family:'宋体';">开始计位数)</span></span></p><p> #expr substr "phone” 4 4 显示7001 /双引号
(3)echo </span>phone | cut -b </strong></span><span style="color:rgb(128,0,0);"><span style="font-size:16px;"><strong>起始位置<span style="font-family:Calibri;">-</span></strong></span><span style="font-family:'宋体';"><span style="font-size:16px;"><strong>结束位置</strong></span> </span></span><span style="color:rgb(128,0,0);">(从<span style="font-family:Calibri;">1</span><span style="font-family:'宋体';">开始计位数)</span></span></p><p> # echo phone | cut -b 4-7 显示7001
# echo phone | cut -b 4,5,6,7 <span style="font-family:'宋体';">显示</span><span style="font-family:Calibri;">7001</span></p><p>########################################</p><p>随机提取1位字符</p><p>#!/bin/bash</p><p>ID='0123456789qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM'</p><p>(echo {#ID} 62)
num=[RANDOM{ID:num:1} </span> /</p><p>num=<span style="color:rgb(128,0,0);">[RANDOM%62+1] 1-62
echo ID | cut -b num
expr substr “ID” num 1
2) 子串替换
( vim :s/老/新/g
vim末行模式常用操作:
:s/old/new ,替换当前行第一个“old” :s/old/new/g ,替换当前行所有的“old”
:n,m s/old/new/g ,替换第n-m行所有的“old” :% s/old/new/g ,替换文件内所有的“old”
:w /root/newfile ,另存为其它文件 :r /etc/filesystems ,读入其他文件内容 :set nu|nonu ,显示/不显示行号 :set ai|noai ,启用/关闭自动缩进 )
echo {phone/老/新}</p><p>echo {phone/6034/****}
echo {phone/1/*} /单斜线只替换第一个匹配值</p><p>echo {phone//1/9} /双斜线替换所有匹配值
########################################
编写脚本:批量修改扩展名txt 改成 doc 提示:循环,掐头去尾
前奏准备:mkdir /test touch /test/{a.txt,b.txt,c.txt,d.txt}
for I in (ls /test/*.txt)</p><p>do</p><p> echo {i/.txt/.doc} / 从左往右,要确保只有一个.txt
done
或
for I in (ls /test/*.txt) /可以把.txt改成1,.doc改成2,把常量换成变量</p><p>do</p><p><spanstyle="color:rgb(128,0,0);">xx={i%.*} /删除从右往左第一个点后所有
mv i xx.doc
done
########################################
3)按条件掐头去尾
#掐头:从左向右删; %去尾 从右向左删
head -1 /etc/passwd A=’root:x:0:0:root:/root:/bin/bash’
echo {A#*:} /把第一个冒号前面的任意删除</p><p><br></p><p>echo {A##*:} /把所有冒号前面的任意删除
echo {A%:*} /从右往左算第一个冒号后的所有</p><p>echo {A%%:*} /把所有冒号后面的任意删除
字符串的匹配删除
basename /a/c/b.txt 掐头 = {A##*/} </p><p>dirname <span style="color:rgb(128,0,0);"> /a/c/</span>b.txt 去尾 = {A%/*}
2.变量初始值处理
1)只取值,{var:-word}</span></p><p>若变量<span style="font-family:Calibri;">var</span><span style="font-family:'宋体';">已存在且非</span><span style="font-family:Calibri;">Null</span><span style="font-family:'宋体';">,则返回 </span><span style="font-family:Calibri;">var 的值;否则返回字串“word”,原变量var的值不受影响。
2)取值+赋值,{var:=word}</span></p><p>若变量<span style="font-family:Calibri;">var</span><span style="font-family:'宋体';">已存在且非</span><span style="font-family:Calibri;">Null</span><span style="font-family:'宋体';">,则返回 </span><span style="font-family:Calibri;">var 的值,原变量值不变;否则返回字串“word”,并将此字串赋值给变量 var。
#echo {TT:-hehe}</p><p>########################################</p><p>例:密码为空,自动给初始密码</p><p> read -p “请输入用户名:<span style="font-family:Calibri;">” </span>user</p><p> read -p “请输入密码:<span style="font-family:Calibri;">” </span>pass</p><p> [ -z user ] && exit
p={pass:-123456}</span></p><p> useradd user &>/dev/null
echo “p“ | passwd --stdin user &>/dev/null
或echo “{pass:-123456}</span>“ | passwd --stdin user &>/dev/null
########################################
求和 1+2+3+4…+100 (5050)
sum=0
for I in {1..100}
do
sum=[sum+i]</p><p> echo sum
done
########################################
求1到x的和,x为用户输入的数
read -p “请输入数:” num
num={num:-100}</p><p>sum=0</p><p>for I in `seq num`</p><p>do</p><p> sum=$[sum+i]
done
二、扩展的脚本技巧
1.使用shell数组
建立数组的方法:
格式1,整体赋值:数组名=(值1 值2 .. .. 值n)
格式2,单个元素赋值:数组名[下标]=值
查看数组元素的方法:
获取单个数组元素:{</span><span style="font-family:'宋体';">数组名</span><span style="font-family:Calibri;">[</span><span style="font-family:'宋体';">下标</span><span style="font-family:Calibri;">]} </span></p><p>获取所有数组元素:<span style="font-family:Calibri;">{数组名[@]} (@或* 都表示所有)
获取数组元素个数:{#</span><span style="font-family:'宋体';">数组名</span><span style="font-family:Calibri;">[@]} </span></p><p>获取连续的多个数组元素:<span style="font-family:Calibri;">{数组名[@]:起始下标:元素个数}
获取某个数组元素的长度:{#</span><span style="font-family:'宋体';">数组名</span><span style="font-family:Calibri;">[</span><span style="font-family:'宋体';">下标</span><span style="font-family:Calibri;">]} </span></p><p>截取数组元素值的一部分:<span style="font-family:Calibri;">{数组名[下标]:起始下标:字符数}
a=(11 22 33) echo {a[0] } echo {a[1] } echo {a[2] } /<span style="font-family:'宋体';">获取单个</span></p><p> {a[*] } {a[@] } /<span style="font-family:'宋体';">获取所有</span></p><p>b[0]='ss' b[1]='bb' b[2]='cc' echo {b[*]}
2.expect预期交互
expect可以为交互式过程(比如FTP、SSH等登录过程)自动输送预先准备的文本或指令,而无需人工干预。触发的依据是预期会出现的特征提示文本。
常见的expect指令:
定义环境变量:set 变量名 变量值
创建交互式进程:spawn 交互式命令行
触发预期交互:expect ”预期会出现的文本关键词:” { send ”发送的文本\r” }
在spawn建立的进程中允许交互指令:interact
########################################
脚本帮我自动输入密码,远程传送数据,预期交互
# yum -y install expect
# rpm -qa | grep expect
#!/bin/bash
for I in {1..254}
do
expect << EOF
set timeout 30
spawn ssh -o StrictHostKeyChecking=no 172.25.0.i /<span style="font-family:'宋体';">交互式命令行 </span></p><p>expect “password” {send “redhat\r” } / <span style="font-family:'宋体';">表示回车</span><span style="font-family:Calibri;">\r </span></p><p>expect “#” {send “touch /root/abc.txt\r” }</p><p>expect “#” {send “exit\r” }</p><p><span style="color:rgb(128,0,0);">EOF</span></p><p>echo “<span style="font-family:'宋体';">连接</span><span style="font-family:Calibri;">172.25.0.i 成功!”
done
删掉这个记录登录过的用户的文件/root/.ssh/known_hosts前面都需要先加入yes 。
man expect /timeout
ssh-******
spawn ssh-copy-id 172.25.0.i </p><p>########################################</p><p> </p><p><strong><span style="color:rgb(63,63,63);">三、正则表达式</span></strong></p><p><strong><span style="color:rgb(63,63,63);">1.概述</span></strong></p><p>一种表达方式:使用<span style="font-family:Calibri;">“ </span><span style="font-family:'宋体';">一串符号 </span><span style="font-family:Calibri;">” </span><span style="font-family:'宋体';">来描述有共同属性的数据。如:语言、手语、眼神</span><span style="font-family:Calibri;">……</span></p><p>计算机里的通用语,使用的是一些规定好的符号<span style="font-family:Calibri;">^
绝大多数软件都支持正则表达式,如ps,word,grep,vim,java,shell,python……
grep、egrep 过滤工具,常用命令选项
-i:忽略字母大小写
-v:条件取反
-c:统计匹配的行数
-q:静默、无任何输出,一般用于检测,看?</span><span style="font-family:'宋体';">返回值,为</span><span style="font-family:Calibri;">0</span><span style="font-family:'宋体';">匹配,否则不匹配</span></p><p>-n<span style="font-family:'宋体';">:显示出匹配结果所在的行号</span></p><p>- -color<span style="font-family:'宋体';">:标红显示匹配字串</span></p><p>-E : 调用egrep</p><p> </p><p>#grep “^” /etc/passwd /空白行
#grep “^root” /etc/passwd
#grep “[0-9]” /etc/passwd
#grep “[A-Z]” /etc/passwd
2.基本正则:
特点:处理单位是单个字符;兼容性强,支持软件多;缺点麻烦
^ 开始
<span style="font-family:'宋体';">结尾</span></span></p><p><span style="color:rgb(0,0,255);">[ ] <span style="font-family:'宋体';">集合,之一 </span><span style="font-family:Calibri;">[a-Z] = [a-zA-Z]</span></span></p><p><span style="color:rgb(0,0,255);">[^] <span style="font-family:'宋体';">取反 </span><span style="font-family:Calibri;">[^abc] </span><span style="font-family:'宋体';">不需要</span><span style="font-family:Calibri;">abc </span></span></p><p><span style="color:rgb(0,0,255);">. <span style="font-family:'宋体';">任意单个字符,与操作系统里的?同义</span></span></p><p><span style="color:rgb(0,0,255);">.. <span style="font-family:'宋体';">任意两个字符</span></span></p><p><span style="color:rgb(0,0,255);">* <span style="font-family:'宋体';">匹配前一个字符出现的任意次 </span><span style="font-family:Calibri;">ab* </span><span style="font-family:'宋体';">一定包含</span><span style="font-family:Calibri;">a</span><span style="font-family:'宋体';">,且</span><span style="font-family:Calibri;">b</span><span style="font-family:'宋体';">可以出现的任意次包括</span><span style="font-family:Calibri;">0</span><span style="font-family:'宋体';">次</span></span></p><p><span style="color:rgb(0,0,255);">.* <span style="font-family:'宋体';">匹配任意所有 与操作系统里的</span><span style="font-family:Calibri;">*</span><span style="font-family:'宋体';">同义 </span><span style="font-family:Calibri;">a.* </span><span style="font-family:'宋体';">以</span><span style="font-family:Calibri;">a</span><span style="font-family:'宋体';">开头的所有</span></span></p><p><span style="color:rgb(0,0,255);">\{n,m\} <span style="font-family:'宋体';">匹配前一个字符出现了</span><span style="font-family:Calibri;">n</span><span style="font-family:'宋体';">到</span><span style="font-family:Calibri;">m</span><span style="font-family:'宋体';">次,</span><span style="font-family:Calibri;">m</span><span style="font-family:'宋体';">不写表示上不封顶 </span><span style="font-family:Calibri;">a\{3,5\} </span><span style="font-family:'宋体';">匹配</span><span style="font-family:Calibri;">3-5</span><span style="font-family:'宋体';">个</span><span style="font-family:Calibri;">a </span></span></p><p><span style="color:rgb(0,0,255);">\{n\} <span style="font-family:'宋体';">匹配前一个字符出现</span><span style="font-family:Calibri;">n</span><span style="font-family:'宋体';">次 </span><span style="font-family:Calibri;">a\{3\} </span><span style="font-family:'宋体';">匹配</span><span style="font-family:Calibri;">3</span><span style="font-family:'宋体';">个</span><span style="font-family:Calibri;">a</span></span></p><p><span style="color:rgb(0,0,255);"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-1-Frame" tabindex="0" data-mathml="<math xmlns="http://www.w3.org/1998/Math/MathML" />" role="presentation" style="position: relative;"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-1" style="width: 0em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0em; height: 0px; font-size: 122%;"><span style="position: absolute; clip: rect(3.845em 1000em 4.152em -999.997em); top: -3.993em; left: 0em;"><span class="mrow" id="MathJax-Span-2"></span><span style="display: inline-block; width: 0px; height: 3.998em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.059em; border-left: 0px solid; width: 0px; height: 0.128em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"></math></span></span><script type="math/tex" id="MathJax-Element-1"></script> 括号里面的东西都被复制了</span></p><p><span style="color:rgb(0,0,255);"> </span></p><p><strong><span style="color:rgb(0,0,255);">3.扩展正则:</span></strong></p><p><span style="color:rgb(0,0,255);">特点:处理单位不是单个字符 <span style="font-family:Calibri;">(ab)* ab</span><span style="font-family:'宋体';">为一个整体</span></span></p><p><span style="color:rgb(0,0,255);">简单,兼容性差 <span style="font-family:Calibri;">grep </span><span style="font-family:'宋体';">不支持扩展正则,</span><span style="font-family:Calibri;">egrep</span><span style="font-family:'宋体';">支持,加强版</span><span style="font-family:Calibri;">grep</span></span></p><p><span style="color:rgb(0,0,255);">简化基本正则:<span style="font-family:Calibri;">\{n,m\} → {n,m} (test|taste) </span><span style="font-family:'宋体';">或者 </span></span></p><p><span style="color:rgb(0,0,255);">添加新的符号: <span style="font-family:Calibri;">+ ? | </span></span><span style="color:rgb(0,0,255);">\b ()</span></p><p><span style="color:rgb(0,0,255);"> 如: <span style="font-family:Calibri;">a+ </span><span style="font-family:'宋体';">表示</span><span style="font-family:Calibri;">a</span><span style="font-family:'宋体';">至少出现一次 </span><span style="font-family:Calibri;">a? </span><span style="font-family:'宋体';">表示</span><span style="font-family:Calibri;">a</span><span style="font-family:'宋体';">可有可无 </span><span style="font-family:Calibri;">taste</span><span style="font-family:'宋体';">?</span></span></p><p><span style="color:rgb(0,0,255);"> \b <span style="font-family:'宋体';">单词分界点,前后都加表示该单词独立 </span><span style="font-family:Calibri;"># grep “\bthe\b” 1.txt</span></span></p><p> </p><p>########################################</p><p><strong>将<span style="font-family:Calibri;">ipv4</span><span style="font-family:'宋体';">地址单独过滤出来</span></strong></p><p> # ifconfig | grep "\b<span style="color:rgb(128,0,0);">[0-9]</span><span style="color:rgb(128,0,0);background:rgb(255,255,0);">\{1,3\}</span><span style="color:rgb(128,0,0);">\.\{1\}</span>[0-9]\{1,3\}\.\{1\}[0-9]\{1,3\}\.\{1\}[0-9]<span style="color:rgb(128,0,0);">\{1,3\}</span>\b" </p><p> </p><p> # ifconfig | grep -E "<span style="color:rgb(128,0,0);">(</span>[0-9]{1,3}\.<span style="color:rgb(128,0,0);">){3}</span>[0-9]<span style="color:rgb(128,0,0);">{1,3}</span>" </p><p>########################################</p><p>2.<span style="font-family:'宋体';">基本元字符</span></p><p>行首尾及单字匹配: <span style="font-family:Calibri;">^ </span><span style="font-family:'宋体';">开始 </span><span style="font-family:Calibri;"> 括号里面的东西都被复制了
3.扩展正则:
特点:处理单位不是单个字符 (ab)* ab为一个整体
简单,兼容性差 grep 不支持扩展正则,egrep支持,加强版grep
简化基本正则:\{n,m\} → {n,m} (test|taste) 或者
添加新的符号: + ? | \b ()
如: a+ 表示a至少出现一次 a? 表示a可有可无 taste?
\b 单词分界点,前后都加表示该单词独立 # grep “\bthe\b” 1.txt
########################################
将ipv4地址单独过滤出来
# ifconfig | grep "\b[0-9]\{1,3\}\.\{1\}[0-9]\{1,3\}\.\{1\}[0-9]\{1,3\}\.\{1\}[0-9]\{1,3\}\b"
# ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}"
########################################
2.基本元字符
行首尾及单字匹配: ^ 开始 结尾 . 任意单个字符
未定义匹配次数: + ? *
{ } 限定表达式匹配的次数:{n} {n,m} {n,}
3.其他元字符
[ ]范围内单字匹配,匹配指定字符i集合内的任何一个字符:
[ ] 内加^ 可取反 : [a|c45_?] [a-z] [A-Z] [0-9] [a-Z0-9] [^A-Z] ^[^a-z]
整体及边界匹配:() | \b \< \>
\ 为转义符号,可以为一些普通字符赋予特殊含义,或者将一些特殊字符变为普通字符。
########################################
过滤 test 或 taste 这两个单字 # grep ‘t[ae]ste\{0,1\}’ 1.txt
过滤不想要 oo 前面有 g 的 # grep ’[^g]oo’ 1.txt
过滤开头不是英文字母 # grep ’^[^aZ]’ 1.txt
过滤行尾结束为小数点.那一行 # grep “\.” 1.txt</span></p><p>过滤出 <span style="font-family:Calibri;">g??d </span><span style="font-family:'宋体';">的字串 </span># grep “g..d” 1.txt</p><p> </p><p>过滤下载文件中包含 <span style="font-family:Calibri;">the </span><span style="font-family:'宋体';">关键字 </span><span style="font-family:Calibri;">#grep 'the' 1.txt</span></p><p>过滤下载文件中不包含 <span style="font-family:Calibri;">the </span><span style="font-family:'宋体';">关键字 </span><span style="font-family:Calibri;"># grep -v 'the' 1.txt</span></p><p>过滤下载文件中不论大小写 <span style="font-family:Calibri;">the </span><span style="font-family:'宋体';">关键字 </span><span style="font-family:Calibri;"># grep -i 'the' 1.txt</span></p><p>过滤 <span style="font-family:Calibri;">test </span><span style="font-family:'宋体';">或 </span><span style="font-family:Calibri;">taste </span><span style="font-family:'宋体';">这两个单字 </span><span style="font-family:Calibri;">#grep 't[ae]st' 1.txt</span></p><p>过滤有 <span style="font-family:Calibri;">oo </span><span style="font-family:'宋体';">的字节 </span><span style="font-family:Calibri;">#grep 'oo' 1.txt</span></p><p>过滤不想要 <span style="font-family:Calibri;">oo </span><span style="font-family:'宋体';">前面有 </span><span style="font-family:Calibri;">g </span><span style="font-family:'宋体';">的 </span><span style="font-family:Calibri;">#grep '[^g]oo' 1.txt</span></p><p>过滤 <span style="font-family:Calibri;">oo </span><span style="font-family:'宋体';">前面不想有小写字节 </span><span style="font-family:Calibri;">#grep '[^a-z]oo' 1.txt</span></p><p>过滤有数字的那一行 <span style="font-family:Calibri;">#grep '[0-9]' 1.txt</span></p><p>过滤以 <span style="font-family:Calibri;">the </span><span style="font-family:'宋体';">开头的 </span><span style="font-family:Calibri;">#grep '^the' 1.txt</span></p><p>过滤以小写字母开头的 <span style="font-family:Calibri;">#grep '^[a-z]' 1.txt</span></p><p>过滤开头不是英文字母 <span style="font-family:Calibri;">#grep '^[^a-zA-Z]' 1.txt</span></p><p>过滤行尾结束为小数点<span style="font-family:Calibri;">.</span><span style="font-family:'宋体';">那一行 </span><span style="font-family:Calibri;">#grep '\.’ 1.txt
过滤空白行 #grep ’^$’ 1.txt
过滤出 g??d 的字串 #grep ‘g..d’ 1.txt
过滤至少两个 o 以上的字串 #grep ‘ooo*’ 1.txt
过滤 g 开头和 g 结尾但是两个 g 之间仅存在至少一个o #grep ‘goo*g’ 1.txt
过滤任意数字的行 #grep ’[0-9][0-9]*’ 1.txt
过滤两个 o 的字串 #grep ‘o\{2\}’ 1.txt
过滤 g 后面接 2 到 5 个 o,然后在接一个 g 的字串 #grep ‘go\{2,5\}g’ 1.txt
过滤 g 后面接 2 个以上 o 的 #grep ‘go\{2,\}g’ 1.txt