shell: shell读取文本
June 4, 2015
都是使用shell自建的命令进行读取,可实际的结果会有很大的差异。
我们先建立一个测试文件a.txt
a b c d #e f g
然后进行字符串自增的方式进行测试。第一个使用重定向<符号来进行读入文件。
#!/bin/bash set -x WR="account >" while read line do WR="$WR>"" >""$line>" done<a.txt echo $WR [/code] <p>最终我们看到输出的结果就是我们期待的 account a b c d #e f g</p> + 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的方式进行读入,但是得到的结果却不是我们期望的
#!/bin/bash set -x WR="account >" grep -v ^# a.txt | while read line do WR=${WR}" >"${line} done echo $WR
最终的输出为:
+ 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循环的方式来进行处理:
#!/bin/bash set -x WR="account >" for line in `grep -v ^# a.txt` do WR=${WR}" >"${line} done echo $WR
最终的输出结果我们所期望的。
+ 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语句放到同一个子进程中。 如下 (请注意其中的 括号
):
#!/bin/bash set -x declare -x WR="account >" grep -v ^# a.txt | ( while read line do WR=${WR}" >"${line} done echo $WR )
得到结果如下:
+ 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
而用重定向的方式就会受很多限制,记得只能是重定向文件,而不能是某个命令的结果。
所以综上所述,我们在做这样的操作的时候要注意管道和子进程的问题。 而且当我们读入的文件不是用n来分割的话,可以使用read 加参数的方式,或者直接先用awk进行处理。
shell读取文本
byTimo is my oasis is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
.
0 Comments