shell读取文本

都是使用shell自建的命令进行读取,可实际的结果会有很大的差异。 我们先建立一个测试文件a.txt c a b c d #e f g 然后进行字符串自增的方式进行测试。第一个使用重定向<符号来进行读入文件。 c #!/bin/bash set -x WR="account " while read line do WR="$WR"" ""$line" done<a.txt echo $WR 最终我们看到输出的结果就是我们期待的 account a b c d #e f g ```c

  • WR=’account ‘ + read line + WR=’account a’ + read line + WR=’account a b’ + read line + WR=’account a b c’ + read line + WR=’account a b c d’ + read line + WR=’account a b c d #e’ + read line + WR=’account a b c d #e f’ + read line + WR=’account a b c d #e f g’ + read line + echo account a b c d ‘#e’ f g account a b c d #e f g

然后我们使用管道和while的方式进行读入,但是得到的结果却不是我们期望的c
#!/bin/bash set -x WR=”account “ grep -v ^# a.txt | while read line do WR=${WR}” “${line} done echo $WR
最终的输出为:c

  • WR=’account ‘ + grep -v ‘^#’ a.txt + read line + WR=’account a’ + read line + WR=’account a b’ + read line + WR=’account a b c’ + read line + WR=’account a b c d’ + read line + WR=’account a b c d f’ + read line + WR=’account a b c d f g’ + read line + echo account account

这样的方式,最终的输出居然只有“account”, 而没有别的内容,也就是只有我们初始化的那个内容,可打开调试我们可以看到明明最后一次自增后的结果是对的,可最终输出的值却不是我们想要的。 本来使用这种方式想处理a.txt这样的文本再传入给read,可最终结果既然不是我们想要的,那就用别的吧。 而重定向导入文件的方式是不能对文件进行在外部进行处理的,只能在while循环内部进行。   于是我们就用最后一个中for循环的方式来进行处理:c
#!/bin/bash set -x WR=”account “ for line in `grep -v ^# a.txt` do WR=${WR}” “${line} done echo $WR
最终的输出结果我们所期望的。c

  • WR=’account ‘ ++ grep -v ‘^#’ a.txt + for line in ‘`grep -v ^# a.txt`‘ + WR=’account a’ + for line in ‘`grep -v ^# a.txt`‘ + WR=’account a b’ + for line in ‘`grep -v ^# a.txt`‘ + WR=’account a b c’ + for line in ‘`grep -v ^# a.txt`‘ + WR=’account a b c d’ + for line in ‘`grep -v ^# a.txt`‘ + WR=’account a b c d f’ + for line in ‘`grep -v ^# a.txt`‘ + WR=’account a b c d f g’ + echo account a b c d f g account a b c d f g

而最终这个结果才是我们真正想要达到的结果。 至于为什么grep -v ^# a.txt | while read line这种方式不行呢? 这个是由于管道造成的。在管道的时候是fork了shell子进程,只有在子进程内这个值才是我们所期待的。 当然我们也可以把最后一个echo语句放到同一个子进程中。 如下 (请注意其中的括号):c
#!/bin/bash set -x declare -x WR=”account “ grep -v ^# a.txt | ( while read line do WR=${WR}” “${line} done echo $WR )
得到结果如下:c

  • declare -x ‘WR=account ‘ + grep -v ‘^#’ a.txt + read line + WR=’account a’ + read line + WR=’account a b’ + read line + WR=’account a b c’ + read line + WR=’account a b c d’ + read line + WR=’account a b c d f’ + read line + WR=’account a b c d f g’ + read line + echo account a b c d f g account a b c d f g