假设test目录下面有a.log、b.log和c.log三个文件:

# ls -1 *.log
a.log
b.log
c.log

现在,我们想要遍历这几个文件,找到关心的信息,例如log文件中是否存在error信息。那么,我们会考虑写一个for循环来处理这个问题:

# for i in `ls -1 *.log | sed '$d'`; do
> grep 'err' $i
> done

非常简单的一个循环,但是执行后会发现以下错误:

grep: a.log: No such file or directory
grep: b.log: No such file or directory
grep: c.log: No such file or directory

非常奇怪,不是*.log这几个文件都在当前目录存在着的吗?为什么这里又找不到呢?
我当时试了各种各样的方法,都是报错,害我一度以为用双引号括起来的文件名会有特殊的效果。结果,灵光一现,就想到用cat命令来检查下,真是柳暗花明啊,当然你也可以想像得到这之间的过程也是多么让人抓狂的:

# cat -A < < EOF
> `ls -1 *.log`
> EOF
^[[00m^[[00ma.log^[[00m$
^[[00mb.log^[[00m$
^[[00mc.log^[[00m$
^[[m$

上面这些奇奇怪怪的东西是Bash的颜色控制码,相信折腾过bash prompt的同学应该对它非常了解,为什么会出现这些控制码呢?因为在我们的~/.bashrc中默认定义了几个alias,其中就有ls命令:

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias ls='ls --color'

可以看到上面的最后一行就是问题的原因所在,找到原因后,就知道怎么解决了。不过这里我们还是不动.bashrc的配置,而是用另外一种方法:

# for i in `\ls -1 *.log`; do
> grep 'err' $i
> done

注意到了吗,用\ls就可以去掉alias的效果,这一点还是阮哥教我的,哈哈。

当然解决的方法很多,另外一种方法是直接使用通配符展开的功能:

for i in *.log; do grep 'err' $i; done

所以有时候眼睛看到的不一点是真的,这世上有很多我们无法用肉眼看到的,需要我们仔细的去揣摩体会。
解决问题的过程是纠结的,但是一旦解决了那种感觉非常开心,当然一直解决不了只能放弃也是非常无奈的事情。