grep无法查找shell传过来的变量?先注意一下文本格式吧! | 张戈博客

  • 时间:
  • 浏览:1

昨天,同事你需用知道发现一个多诡异的问题,grep无法搜索shell中的变量,嘴笨 很惊讶。到他所说的服务器上试了下,还青春恋爱物语不行!

相当于却说刚刚一个多要求:

①、有个文本为userid.txt,里面每一行一个多用户id,例如如下:

0001
0003
0005
0007
0009

②、另外还俩个多文本为record.txt,里面是所有用户的操作记录,一行四根,但会 包中含id,例如如下:

[12 11 2014 11:03,198 INFO] userId:0001 gilettype:3
[12 11 2014 12:12,198 INFO] userId:0002 gilettype:3
[12 11 2014 13:02,198 INFO] userId:0003 gilettype:1
[12 11 2014 14:33,198 INFO] userId:0001 gilettype:3
[12 11 2014 15:13,198 INFO] userId:0002 gilettype:2
[12 11 2014 16:43,198 INFO] userId:0003 gilettype:1
[12 11 2014 17:32,198 INFO] userId:0001 gilettype:3
[12 11 2014 18:16,198 INFO] userId:0002 gilettype:1
[12 11 2014 19:25,198 INFO] userId:0003 gilettype:2

③、现在他要求循环取出userid.txt中每一行ID值,但会 去record.txt去查找并保存结果。

实现五种需求刚刚很简单,根本难不倒他,只要使用while read + grep 就能拿出。可问题是明明record.txt里面中含什么id,却无法输出结果??

我顺便写了一个多测试脚本测试了下:

#!/bin/bash
while read userId;
do
        echo $userId
        grep $userId record.txt
done <userid.txt

发现脚本需用打印echo $userId,却无法grep到??而实际上record.txt里面是有五种id的!还真诡异!

先百度搜索了一下【grep 无法搜索变量】,还真有不少例如问题,比如:http://bbs.chinaunix.net/thread-123113-1-1.html

根据经验,对于五种诡异的问题,我首先会想到是有的是系统有问题,却说系统有问题你咋样会折腾有的是错!

于是把他的文件拷贝到某些服务器,发现青春恋爱物语需用了!!!难道青春恋爱物语系统问题么?

第一台是SUSE Linux,第二台是Centos,难道和系统发行版有关系?

并且,同事在第二台服务器上完成了他的项目。但五种问题却突然 留在我的脑子里,挥之不去。


今天,我决定再次研究下五种问题,看看是有的是有某些导致 。我先在那台SUSE Linux上,手工编写所需文件:

[[email protected] ~]# vim 1.txt

1111
3333
5555

[[email protected] ~]# vim 2.txt

1111
2222
3333
4444
5555
6666

[[email protected] ~]# vim test.sh

#!/bin/bash
cat 1.txt|while read userId;
do 
        grep $userId 2.txt
done

结果,发现青春恋爱物语需用输出结果!证明这系统没法问题啊!于是再一次测试了一下昨天的脚本,发现还是无法输出。

于是使用 -x 参数 调试一下脚本:

先修改脚本代码:

#!/bin/bash
cat userid.txt|while read userId;
do 
        grep $userId record.txt
        sleep 3
done

但会 ,带 -x 参数执行:

[[email protected] ~]#  sh -x test
+ cat userid.txt
+ read userId
+ grep $'0001\r' record.txt
+ sleep 3
+ read userId
+ grep $'0003\r' record.txt
+ sleep 3
+ read userId
+ grep $'0005\r' record.txt
+ sleep 3

难怪找还后能 ,grep的变量可能性变了!0001变成了 $’0001\r’ !

就看\r,立马想到是文本中的换行符,可为毛会输出换行符呢?想到博客刚刚写的《Linux终端:用cat命令查看不可见字符》,继续改了一下代码:

#!/bin/bash
cat -A userid.txt|while read userId;
do 
        grep $userId record.txt
        sleep 3
done

执行后恍然大悟:

[[email protected] ~]#  sh -x test
+ cat -A userid.txt
+ read userId
+ grep '0001^M$' record.txt
+ sleep 3
+ read userId
+ grep '0003^M$' record.txt
+ sleep 3
+ read userId
+ grep '0005^M$' record.txt
+ sleep 3

刚刚是dos下的文本格式,问了下同事,他还青春恋爱物语从Windows下导过来的! — —||

也却说说,userid.txt五种文本的换行符是Windows格式,在Linux下读取会中含^M。

却说解决上述问题,就很明了了,要么转换userid.txt的换行格式,要不就修改代码,去掉 多余的字符!

试了下转换格式,发现青春恋爱物语转换不成功,可能性是我没找对法律土办法,暂时先不折腾了!

直接如下修改代码,就拿出了:

#!/bin/bash
cat -A userid.txt|while read userId;
do
        #利用cut命令取出 ^ 刚刚的数字偏离

:
        id=`echo $userId | cut -d"^" -f1`
        grep $id record.txt
done

好了,搞了半天刚刚是dos和unix的换行符问题!o(︶︿︶)o 唉!还是经验严重不足啊!

网上什么问grep无法搜索变量的朋友 ,赶紧看看是有的是文本格式造成的!现在,你需用很纳闷的是,为毛在另一台centos系统需用直接grep??咋样会在SUSE系统就不行?

可能性和发行版没关系搞笑的话,那造成一个多不同结果的导致 就还后能 并能 一个多:在我用sz+rz命令将所有文本传送到centos的过程中,文件很可能性被自动转格式了!好吧,具体就不深究了,有兴趣的需用试试看。