记录一次关于截取字符串的天坑,引以为戒

事情是这样的

我想截取本机的Ip如10.0.0.128最后的128,编写脚本用

代码

hostname -I

 

最开始,用cut,分隔符为 [    .   ],小黑点,作为分隔符

代码

hostname -I | cut -d. -f4

 

 结果看似很美好,成功取出128

然后

我需要这个128,传送给变量,变量传给sed,以128作为正则表达式关键词,删除以下文本。命令类似于    sed -i /${PAICHU}/d SCANIP.txt,${PAICHU}变量期望是128

 

 然而,当我开始运行这个脚本,总是无法删除指定的128这一行

我就怀疑人生了

为什么明明是128却不能删除?

我开始怀疑是不是sed没有读取到变量,搜索了很多sed正则表达式使用变量的方法,发现该方法没问题。

又尝试自己写另外的脚本删除128,没有问题

 

这就奇怪了,为什么128删除不了?

于是我开始怀疑,是否是因为变量中多了某种符号,类似于 “128 ”,128后面跟了空格

于是乎,我执行了一下命令

hostname -I | cut -d. -f4 >> dalang.txt

取出128这列,输出到dalang.txt观察

 

 注意看,我在vim用set list命令128后面居然跟了个空格,也就是说我是在匹配 128+一个空格 这个关键字,而我的文本中并没有128+空格,

那么就是说, sed -i /${PAICHU}/d SCANIP.txt,命令将不会匹配到128这行,也就不会删除!!!!!!!!!!!!!!!如此一来会影响我接下来的脚本执行情况

此时才如梦方醒,原来是这样导致的失败,多么微小的错误!!!!!!!!!!!!!

 

于是我改用了awk来取列 

PAICHU=$(hostname -I | awk -F[ .]+ '{print $4}')

分隔符指定为空格或者.,取hostname -I的第四列就不会出现空格

 

总结:

1、正则表达式的匹配规则还要多加揣摩,实在不行利用在线正则表达式测试工具来测试是否条件写的正确

2、linux中的文本看似没毛病,但是存在很多坑,如果实在无法拿捏输出结果,可以输出结果到一个文本,vim 命令行:set list看隐藏符号,可能空格很坑

3、bash -x test.sh可以跟踪脚本的执行,如果存在问题,首先使用此工具,可以快速定位问题,

 

变量会替换为值,可以快速定位问题

4、sed正则表达删除行,sed -i /${PAICHU}/d SCANIP.txt

5,awk取列很好用

6、对于bug,不能纠结于一个点,要多找方法去定位

7、标准输出赋值给变量

PAICHU=$(hostname -I | awk -F[ .]+ '{print $4}')

$()包围标准输出命令