Shell如何解决文件流管道的文本拼接失效问题
前言:
近期由于业务的需要,需实现通过监控日志文件的内容并定时将日志的有效内容通过邮件进行告警。
文本内容的格式如下:
1 aaa 2 bbb 4 ccc 7 ddd
希望输出:
bbb
ccc
版本一
#!/bin/sh msg="" echo -e "start-msg=${msg}" cat aa.txt | while read line do num=`echo ${line} | awk -F ' ' '{ print $1 }'` text=`echo ${line} | awk -F ' ' '{ print $2 }'` if [ $((num%2)) = 0 ]; then # 按行拼接 msg="${msg}\n${text}" echo -e "msg=${msg}" fi done echo -e "final-msg=${msg}" echo "-- all done --"
版本二修改如下:
在循环内部增加变量"index",最后通过判断"index"是否到达最后一行进行结果输出
#!/bin/sh msg="" #通过判断行数决定是否输出 total_row=`wc -l aa.txt | awk '{ print $1 }'` index=0 echo -e "start-msg=${msg}" cat aa.txt | while read line do ((index++)) num=`echo ${line} | awk -F ' ' '{ print $1 }'` text=`echo ${line} | awk -F ' ' '{ print $2 }'` if [ $((num%2)) = 1 ]; then # 按行拼接 msg="${msg}\n${text}" echo -e "msg=${msg}" fi if [ ${index} = ${total_row} ]; then echo -e "final-msg=${msg}" fi done echo "-- all done --"
分析:
如上版本一之所以输出为空是因为"msg"在循环内部是属于局部变量,循环内部赋值有效,且打印的局部变量值不为空,但随之cat管道关闭,子进程被关闭,msg的值又恢复为初始值"'。
附:
管道外的局部变量赋值失效的场景可以使用如下命令进行测试
$ a=1; echo $a; echo "hello, world" | while read line ; do ((a++)); echo $a; done; echo $a
-------- 以上内容纯属个人学习总结,不代表任何团体或单位。若有理解不到之处请见谅!---------