echo命令的一个疑问

阅读更多

今天在做日志处理的时候发现了这么一个问题:

有这么一段数据,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

 

 

 

 

------------------------------------分割线---------------------------------------------

参考了CU里的shell板块,问题可以这么解决:

 

IFS=$'\n';for i in $(

 

 

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 $(:server1 ip1 password1
server2 ip2 password2
server3 ip3 password3:

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

$ (IFS=$'\n';for i in $(:server1 ip1 password1:
:server2 ip2 password2:
:server3 ip3 password3:

 

----EOF-------

你可能感兴趣的:(shell,echo)