Linux三剑客之sed多行处理

业务爸爸:小毛驴我有个历史交易记录数据,以ID开头(如ID Apple450001315857834)到 TIME结束(如TIME 1673615211)表示一条完整的记录,其中中间有RFTIME行(如RFTIME 1673696951)表示交易正常,反正是交易异常 。现在需要把交易异常的记录拿出来 。数据如下:
root@VM-2-15-ubuntu:~# cat list.txt IDapple450001315857834PR25RFTIME1673696951SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017IDapple450001315857834PR25RFTIME1673696951SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017IDapple450001315857834PR25RFTIME1673696951SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017IDapple450001315857834PR25RFTIME1673696951SAVEIDxmlCAtgyXHTIME1673615211IDapple450001315857834PR25RFTIME1673696951SAVEIDxmlCAtgyXHTIME1673615211IDapple450001315857834PR25RFTIME1673696951SAVEIDxmlCAtgyXHTIME1673615211IDapple450001315857834PR25RFTIME1673696951SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017小毛驴:安排!
拿到这个需求,小毛驴第一就想到了用sed多行处理,而且也洋洋洒洒的写出来第一个版本:
sed -nr ':a;N;/TIME/!ba;/RFTIME/!p;' list.txtroot@VM-2-15-ubuntu:~# sed -nr ':a;N;/TIME/!ba;/RFTIME/!p;' list.txt SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017SAVEIDxmlCAtgyXHTIME1673615211SAVEIDxmlCAtgyXHTIME1673615211SAVEIDxmlCAtgyXHTIME1673615211SAVEIDxmlCAtgyXHTIME1673615211IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017很明显上面的不符合需求,这个时候,很明显是数据锚定有问题,此时我只能请出sed的debug工具---sedsed 。
sedsed安装
【Linux三剑客之sed多行处理】cd /usr/local/sbinwget https://raw.Githubusercontent.com/aureliojargas/sedsed/main/sedsed.pywget https://raw.githubusercontent.com/aureliojargas/sedparse/main/sedparse.pymv sedsed.py sedsedchmod +x sedsedsed三个空间 如下图 。PATT: sedsed输出显示模式空间缓冲区的内容COMM: 显示正在执行的命令HOLD: 显示hold sapce缓冲区的内容sed一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(pattern space);接着用sed命令处理缓冲区(pattern space)中的内容,处理完成后,把缓冲区(pattern space)的内容送往屏幕.接着清空缓冲区(pattern space),处理下一行,这样不断重复,直到文件末尾.sed一次处理一行内容,处理时,先读入一行,去掉尾部换行符,存入pattern space,执行编辑命令.处理完毕,除非加了-n参数,把现在的pattern space打印出来,在后边打印曾去掉的换行符.pattern space(模式空间)相当于sed车间把流内容在这里处理.hold space(保留空间)相当于仓库,加工的半成品在这里临时储存(当然加工完的成品也在这里存储).

Linux三剑客之sed多行处理

文章插图
 
开始调试
PATT:IDapple450001315857834$ //模式空间 读入第一行HOLD:$// 此时hold sapce为空COMM::a// 执行条件选择aCOMM:N// 追加读一行数据PATT:IDapple450001315857834nPR25$ // 模式空间此时内容HOLD:$ // 此时hold sapce为空COMM:/TIME/ !b a//执行条件选择a,不满足,继续读取下一行COMM:NPATT:IDapple450001315857834nPR25nRFTIME1673696951$ // 模式空间此时内容HOLD:$// 此时hold sapce为空COMM:/TIME/ !b a //执行条件选择a,满足了---竟然满足了 。问题就出现在这了 。COMM:/RFTIME/ !p // 满足就不打印PATT:IDapple450001315857834nPR25nRFTIME1673696951$ // 模式空间此时内容将会被清空HOLD:$ PATT:SAVEIDxmlCAtgyXH$ // 模式空间读入一个新行HOLD:$COMM::aCOMM:NPATT:SAVEIDxmlCAtgyXHnTIME1673615211$HOLD:$COMM:/TIME/ !b a 
通过上面debug我们可以看出是因为RFTIME匹配到TIME,这个真是不细心的的原因 。改(尝试了30多分钟,才用debug工具看出来,真是xx 。)
root@VM-2-15-ubuntu:~# sed -nr ':a;N;/bTIME/!ba;/RFTIME/!p;' list.txt IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017IDapple450001216057835PR25SAVEIDxmlCAtgyXHTIME1663042017




    推荐阅读