论坛首页 综合技术论坛

echo命令的一个疑问

浏览 3143 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-06  

今天在做日志处理的时候发现了这么一个问题,先记录一下,等有大段空闲时间再来彻底了解下这个问题:

有这么一段数据,test.log

 

2011-12-12 00:01:25
2011-12-12 00:03:25
2011-12-12 00:05:25
2011-12-12 00:07:26
2011-12-12 00:09:26

 

 (结尾的$是通过vim里的 set list! 命令显示出来,表示的是一行结束)

 

当我通过一个for循环打印出这段数据的时候,问题出现了:

 

for x in `cat test.log`;do echo $x;done

 

 我期望的数据输入是每行的内容都是“2011-12-12 00:09:26”这种格式,但是结果却是这样:

 

2011-12-12
00:01:25
2011-12-12
00:03:25
2011-12-12
00:05:25
2011-12-12
00:07:26
2011-12-12
00:09:26

 空格被echo当成了换行输出,在vim输入set :list!,得到的结果没有异常:

 

2011-12-12 00:01:25$
2011-12-12 00:03:25$
2011-12-12 00:05:25$
2011-12-12 00:07:26$
2011-12-12 00:09:26$

 (空格还是空格,$符号位一行的结尾)

 

 

具体原因待查,不过已经找到一个替代方法:

 

cat test.log | while read x;do echo $x;done

 结果如下:

 

2011-12-12 00:01:25
2011-12-12 00:03:25
2011-12-12 00:05:25
2011-12-12 00:07:26
2011-12-12 00:09:26

 

   发表时间:2012-12-08   最后修改:2013-08-23
检查一下你的环境变量IFS的设置
如果IFS设成了空格' ',就会导致这样的结果

0 请登录后投票
   发表时间:2012-12-08  
jamcode 写道
检查一下你的环境变量IFS的设置
如果IFS设成了空格' ',就会导致这样的结果

Jex.im

好的!我估计也是分隔符的问题。
多谢
0 请登录后投票
   发表时间:2012-12-13  
------------------------------------分割线---------------------------------------------
参考了CU里的shell板块,问题可以这么解决:

IFS=$'\n';for i in $(<test.log);do echo $i:;done


shell手册里的解释:
$IFS
内部字段分隔符
此变量决定Bash如何分割字段,或是解释字符串时的字标识分割。
$IFS默认是空白字符(空格,制表符和新行符),它可以被重新设置。例如,在解释一个以逗号分割的数据文件里可设置成逗号分割。

IFS='\n'与 IFS=$'\n'是不一样的赋值:
IFS=$'\n'是指让bash按照ANSI C来解释$'string'中的string。


IFS为系统变量,对shell起作用,用于word splitting和read.
awk里试用自己的字段分隔符:FS定义。

blackold网友的一段代码说明了这个问题:
$ echo $0
bash

$ echo -En '\n'|xxd
0000000: 5c6e \n

$ (IFS='\n';for i in $(<urfile);do echo $i:;done)
:server1 ip1 password1
server2 ip2 password2
server3 ip3 password3:

$ echo -En $'\n'|xxd
0000000: 0a .

$ (IFS=$'\n';for i in $(<urfile);do echo $i:;done)
:server1 ip1 password1:
:server2 ip2 password2:
:server3 ip3 password3:

----EOF-------
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics