shell中定位字符的方式,包括常见的分割:按位置分隔,按指定的字符串截取,按照指定要求(如指定后缀)分割。
字符串操作
一、按位置分隔
Linux shell 截取字符变量的前8位,有方法如下:
1.
1
expr substr “$a” 1 8
2.
1
echo $a|awk ‘{print substr(,1,8)}'
3.
1
echo $a|cut -c1-8
4.
1
expr $a : ‘\(.\\).*'
5.
1
echo $a|dd bs=1 count=8 2>/dev/null
二、按指定的字符串截取
1. 第一种方法:
1 | {varible##*string} #从左向右截取最后一个string后的字符串 |
“*”只是一个通配符可以不要
例子:
1 | MYVAR=foodforthought.jpg |
2. 第二种方法:
${varible:n1:n2}:截取变量varible从n1到n2之间的字符串。
可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。试着在 bash 中输入以下行:
1 | EXCLAIM=cowabunga |
这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。
三、按照指定要求分割:
比如获取后缀名
1 | ls -al | cut -d “.” -f2 |
应用心得:
1 | $MYVAR="12|dadg" |
四、批量替换所有文件中的指定字符串
sed -i “s/原字符串/新字符串/g” grep 原字符串 -rl 所在目录
1 | sed -i "s/mahuinan/huinanma/g" 'grep mahuinan -rl /www' |
1)只替换第1个子串
格式:${变量名/old/new}
2)替换全部子串
格式:${变量名//old/new}
将phone字符串中的所有8都替换为X:
五、awk 提取两个字符串之间的内容
1 | /bin/bash |
六、shell下在while循环中使用ssh命令的问题
1 现象描述 最近使用ssh批量执行命令(已经做了密钥互信了),脚本读取配置文件中的主机列表(内容为每行一台主机IP地址),然后执行,可是每次只是执行第一台,就退出循环了。
2 排查思路 由于脚本比较简单,只是读取主机,然后ssh而已,所以问题应该出现在ssh上
3 确定问题 搞不通ssh命令为什么会导致shell退出,最后上网搜了一下才找到答案。
ssh命令在每次执行时,会读取所有的标准输入中的内容。
对于while循环,当按照如下方式使用时:
while read Line do
echo $Line done < $filename ` 这里使用重定向,将文件内容输入到while命令,while命令每次使用read从输入中读取一行数据。 问题就在这里,如果在while循环中调用了ssh命令,那么ssh就会把当前输入中所有的数据读走,也就是重定向给while命令的数据,都被ssh命令读走了,以至于下次循环的时候,read读到的内容为空,导致循环提前结束。
4 处理结果
解决这个问题两种方式使用ssh的-n参数:用/dev/null来当ssh的输入,阻止ssh读取本地的标准输入内容。ssh xxxx < /dev/null 重定向shell命令的输入