<返回更多

Linux三剑客之sed多行处理

2023-04-03  今日头条  小毛驴的烂笔头
加入收藏

业务爸爸:小毛驴我有个历史交易记录数据,以ID开头(如ID Apple450001315857834)到 TIME结束(如TIME 1673615211)表示一条完整的记录,其中中间有RFTIME行(如RFTIME 1673696951)表示交易正常,反正是交易异常。现在需要把交易异常的记录拿出来。数据如下:

root@VM-2-15-ubuntu:~# cat list.txt 
ID      apple450001315857834
PR      25
RFTIME  1673696951
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
ID      apple450001315857834
PR      25
RFTIME  1673696951
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
ID      apple450001315857834
PR      25
RFTIME  1673696951
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
ID      apple450001315857834
PR      25
RFTIME  1673696951
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001315857834
PR      25
RFTIME  1673696951
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001315857834
PR      25
RFTIME  1673696951
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001315857834
PR      25
RFTIME  1673696951
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017

小毛驴:安排!

拿到这个需求,小毛驴第一就想到了用sed多行处理,而且也洋洋洒洒的写出来第一个版本:

sed -nr ':a;N;/TIME/!ba;/RFTIME/!p;' list.txt

root@VM-2-15-ubuntu:~# sed -nr ':a;N;/TIME/!ba;/RFTIME/!p;' list.txt 
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
SAVEID  xmlCAtgyXH
TIME    1673615211
SAVEID  xmlCAtgyXH
TIME    1673615211
SAVEID  xmlCAtgyXH
TIME    1673615211
SAVEID  xmlCAtgyXH
TIME    1673615211
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017

很明显上面的不符合需求,这个时候,很明显是数据锚定有问题, 此时我只能请出sed的debug工具---sedsed。

sedsed安装

cd /usr/local/sbin
wget https://raw.Githubusercontent.com/aureliojargas/sedsed/main/sedsed.py
wget https://raw.githubusercontent.com/aureliojargas/sedparse/main/sedparse.py
mv sedsed.py sedsed
chmod +x sedsed

sed三个空间 如下图。
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(保留空间)相当于仓库,加工的半成品在这里临时储存(当然加工完的成品也在这里存储).

 

开始调试

PATT:ID      apple450001315857834$ //模式空间 读入第一行
HOLD:$   // 此时hold sapce为空
COMM::a  // 执行条件选择a
COMM:N   // 追加读一行数据
PATT:ID      apple450001315857834nPR      25$ // 模式空间此时内容
HOLD:$ // 此时hold sapce为空
COMM:/TIME/ !b a  //执行条件选择a,不满足,继续读取下一行
COMM:N
PATT:ID      apple450001315857834nPR      25nRFTIME  1673696951$ // 模式空间此时内容
HOLD:$  // 此时hold sapce为空
COMM:/TIME/ !b a //执行条件选择a,满足了---竟然满足了。问题就出现在这了。
COMM:/RFTIME/ !p // 满足就不打印
PATT:ID      apple450001315857834nPR      25nRFTIME  1673696951$ // 模式空间此时内容将会被清空
HOLD:$ 
PATT:SAVEID  xmlCAtgyXH$ // 模式空间读入一个新行
HOLD:$
COMM::a
COMM:N
PATT:SAVEID  xmlCAtgyXHnTIME    1673615211$
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 
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
ID      apple450001216057835
PR      25
SAVEID  xmlCAtgyXH
TIME    1663042017
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>