【发布时间】:2021-12-22 23:54:25
【问题描述】:
想象一下,我有一些聊天记录协议。它可能看起来像这样:
MSG sender|reciever2: Hello its meCRLF
MSG bob|anna: Hello annaCRLF
MSG bob|anna: How are youCRLF
MSG anna|bob: Im fine, you?CRLF
MSG bob|anna: Same, wanna hang out some time?CRLF
MSG anna|bob: YesCRLF
MSG bob|peter: hey im asking anna to hang out lolCRLF
MSG anna|bob: for sureCRLF
MSG anna|bob: maybe in a few weeks?CRLF
我只想获得 Anna 和 Bob 之间的聊天,但只想知道发件人的姓名一次,直到另一个聊天伙伴开始。
我已经归档的是这个 sed 脚本。
s/^MSG\s+(anna|bob)\|(anna|bob)\:\s{1}(.+)CRLF$/\1: "\3"/g
t end
/^.*/d
:end
这会创建:
bob: "Hello anna"
bob: "How are you"
anna: "Im fine, you?"
bob: "Same, wanna hang out some time?"
anna: "Yes"
anna: "for sure"
anna: "maybe in a few weeks?"
但我想要类似的东西:
bob:
Hello anna
How are you
anna
Im fine, you?
bob:
Same, wanna hang out some time?
anna:
Yes
for sure
maybe in a few weeks?
那么,如何在一个鲍勃之后删除所有鲍勃,直到下一个安娜来?
请注意,这是我拥有可以使用 sed 的一些东西。这必须在带有 sed (GNU sed) 4.7 Packaged by Debian 的 Ubuntu Linux 系统上运行
【问题讨论】:
-
CRLFs 是文字文本,而不是换行符吗? -
是的。这是文字。这是虚构协议定义的一部分。由于这是一个文本文件,因此文件末尾有
\n。我已经在我的短 sed 脚本中删除了CLRF。 -
sed会很痛苦;你确定你不能接受 Awk 中的解决方案,甚至是纯 shell 脚本吗? -
我可以建议的是,将用户名捕获到保留空间,然后将保留空间附加到模式空间并检查换行符之后的字符串是否与字符串的开头相同。懒得解决这个问题,但是像
sed '/\(anna|bob\|bob|anna\)/!d;s/^MSG [^|]*|//;G;s/^\([^:]*\): \(.*\)\n\1/\2/p;t;p;s/: .*//;h'这样的东西在 MacOS 上会给我语法错误,但可能在 Linux 上进行一些调整。 (可能edit 指定您的平台;重要的sed脚本很少可移植。) -
@KamilCuk 只是出于培训原因。我自己创造了这个问题。这不是评分,只是为了学习sed。而且我总是很想学习一些新东西,所以我总是试图从中挑战学习。确实,通过您的解决方案,我已经完成了。
标签: sed