业务爸爸:小毛驴我有个历史交易记录数据,以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