![使用公共字符串“Message”按特定顺序分割文本](https://linux22.com/image/135548/%E4%BD%BF%E7%94%A8%E5%85%AC%E5%85%B1%E5%AD%97%E7%AC%A6%E4%B8%B2%E2%80%9CMessage%E2%80%9D%E6%8C%89%E7%89%B9%E5%AE%9A%E9%A1%BA%E5%BA%8F%E5%88%86%E5%89%B2%E6%96%87%E6%9C%AC.png)
我有一个包含以下内容的文本文件
$ cat foo.txt
some text
[email protected]
8903457923
2018-02-09 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message
some text
[email protected]
8903457923
2018-02-05 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message
我想得到以下输出
$ cat foo.txt
some text [email protected] 8903457923 2018-02-09 07:12 (Asia/Kolkata) again some text over her some more text again Message
some text [email protected] 8903457923 2018-02-05 07:12 (Asia/Kolkata) again some text over here some more text again Message
我想我可以使用 tr 并将“Message”作为通用字符串来实现这一点。但不确定如何实施。
答案1
如果当前行不是“Message”,则将该行追加到列表中,并与OFS连接;当您看到“Message”时,打印当前列表(由 OFS 与当前“Message”行连接):
awk '/^Message$/ { print t OFS $0 ORS; t=""; } !/^Message$/ { t=(t ? t OFS $0 : $0) }' < foo.txt
该t=(t ? t OFS $0 : $0)
部分是三元运算符;它检查是否t
为空;如果是,则将当前行分配给它;否则,将当前值附加到 OFS,后跟当前行。
输出:
some text [email protected] 8903457923 2018-02-09 07:12 (Asia/Kolkata) again some text over here some more text again Message
some text [email protected] 8903457923 2018-02-05 07:12 (Asia/Kolkata) again some text over here some more text again Message
答案2
使用 AWK 更简单的方法:
awk 'BEGIN { ORS=RS="Message\n" } gsub("\n"," ")' ./in.txt
答案3
使用tr
和sed
:
tr '\n' '\t' <foo.txt | sed -e $'s/Message\\\t/Message\\\n\\\n/g'
这会将所有换行符转换为制表符,然后在每次出现后添加两个换行符Message
答案4
最简单、最直接的方法是:
perl -lpe '$\ = /^Message$/ ? "\n\n" : " "' foo.txt
或者使用awk
它是:
awk 'ORS = /^Message$/ ? RS RS : " "'
吸食该文件,-0777
然后整个文件就是一个大字符串,正则表达式在其上/(.*?)^(Message\n)/msg
进行操作。正则表达式查看与该行相邻的最短块,Message
并将该块存储在 中$1
,将 nessage 行存储在 中$2
。该块由换行符组成,换行符全局替换为空格,并且此转换的结果tr/\n/ /r
被传递到print
。while
只要找到块+消息行,循环就会继续进行。
perl -ln -0777e 'print $1 =~ tr/\n/ /r, $2 while /(.*?)^(Message\n)/msg' foo.txt
我们可以使用该sed
工具来执行这项工作,如下所示:
sed -e '
$!N;G;s/\n/ / ;# put 2 lines in pattern space
/ Message\n$/b ;# one message block has been found
s/\(.*\)\(.\)/\2\1/;D ;# go back to read the next line into pattern space
' foo.txt