专栏首页张戈的专栏grep无法查找shell传过来的变量?先注意一下文本格式吧!

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

昨天,同事告诉我发现一个诡异的问题,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 上,手工编写所需文件:

[root@localhost ~]# vim 1.txt

1111
3333
5555

[root@localhost ~]# vim 2.txt

1111
2222
3333
4444
5555
6666

[root@localhost ~]# 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 参数执行:

[root@localhost ~]#  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

执行后恍然大悟:

[root@localhost ~]#  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 系统就不行?

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 博客集成Hitokoto·一言经典语句功能

    Hitokoto·一言是一个挺有意思的项目,官方的自我介绍如下: 一言网(Hitokoto.cn)创立于 2016 年,隶属于萌创 Team,目前网站主要提供一...

    张戈
  • SEO养博客神器:同步文章(或摘要)到新浪博客的WordPress插件

    了解 SEO 的站长都会另外用心做几个博客,起到 SEO 辅助作用。通常说的养博客主要是养 BSP 博客。比如新浪博客,网易博客,百度空间,网易博客,新浪博客,...

    张戈
  • 利用placeholder属性来添加输入框默认文字提示,提高用户体验

    这个是我老早就在用的方法,本不打算分享,因为网上随便都能搜得到,感觉没有分享的必要。鉴于中国博客联盟有朋友问到了这问题,所以还是简单的整理下,希望能帮到部分不了...

    张戈
  • MySQL入门学习笔记——七周数据分析师实战作业

    本篇推送主要涉及SQL语言中较为复杂的子查询与函数嵌套。 虽然这个MySQL系列取名为MySQL基础入门,但是个人不打算做单个函数的用法总结,或者说简单罗列,...

    数据小磨坊
  • 运营数据库系列之可扩展性

    这篇博客文章是CDP中Cloudera的运营数据库(OpDB)系列文章的一部分。每篇文章都会详细介绍新功能。从该系列的开头开始,请参阅《CDP中的运营数据库》,...

    大数据杂货铺
  • 泛函编程(7)-数据结构-List-折叠算法

         折叠算法是List的典型算法。通过折叠算法可以实现众多函数组合(function composition)。所以折叠算法也是泛函编程里的基本组件(fu...

    用户1150956
  • RTMP、RTSP/OVIF、GB/T28181视频流媒体服务器的视频传输方式有哪几种?

    我们流媒体服务器可以传输多种格式的视频文件,能够比较好的兼容ios、android系统,包括电脑系统和网页无插件直播。本文我打算给大家讲一下流媒体服务器的传输方...

    EasyNVR
  • 基于D3.js实现分类多标签的Tree型结构可视化

    今天新来的实习生需要对部分分类文本进行多标签的检测,即根据已构建好的一、二级标签Excel文档,对众包平台人工标注的数据以及机器标注的数据进行评测。

    用户1332428
  • 基于D3.js实现分类多标签的Tree型结构可视化

    今天新来的实习生需要对部分分类文本进行多标签的检测,即根据已构建好的一、二级标签Excel文档,对众包平台人工标注的数据以及机器标注的数据进行评测。 此情此景...

    流川枫
  • 【SpringBoot】在SpringBoot中集成日志收集

    瑞新

扫码关注云+社区

领取腾讯云代金券