如何在sed中替换可选多行上的字符串?

时间:2016-03-29 09:57:32

标签: regex bash awk sed

我有以下字符串:

Title 1:::::some message

Title 2:::::another message

Title 3:::::this time

- a longer
- message
- here

Title 4:::::another short one

Title 5:::::and another

- longish
- one here

我正在尝试将上面的sed替换为以下格式:

{ "values" : [{"title":"Title 1","message":"some message"}]},

{ "values" : [{"title":"Title 2","message":"another message"}]},

{ "values" : [{"title":"Title 3","message":"this time

- a longer
- message
- here"}]},

{ "values" : [{"title":"Title 4","message":"another short one"}]},

{ "values" : [{"title":"Title 5","message":"and another

- longish
- one here"}]},

我知道Perl可能会更容易,但我特别想知道如何使用sed。如您所见,它可能是也可能不是多行匹配。

到目前为止,我有:

sed 'N; s/\(.*\):::::\(.*\)/{ "values" : [{"title":"\1","message":"\2"}]},/'

结果如下:

{ "values" : [{"title":"Title 1","message":"some message
"}]},
{ "values" : [{"title":"Title 2","message":"another message
"}]},
{ "values" : [{"title":"Title 3","message":"this time
"}]},
- a longer
- message
- here

{ "values" : [{"title":"Title 4","message":"another short one
"}]},
{ "values" : [{"title":"Title 5","message":"and another
"}]},
- longish
- one here

使用sed正确完成此操作的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

您可以使用awk:

awk -F ':{5}' 'function write(t, m) {
   printf "{ \"values\" : [{\"title\":\"%s\",\"message\":\"%s\"}]},\n\n", t, m 
}
NF==2 {
   if (m != "")
      write(t, m)
   t=$1
   m=$2
   next
}
NF {
   m = m ORS $0
}
END {
   write(t, m)
}' file

<强>输出:

{ "values" : [{"title":"Title 1","message":"some message"}]},

{ "values" : [{"title":"Title 2","message":"another message"}]},

{ "values" : [{"title":"Title 3","message":"this time
- a longer
- message
- here"}]},

{ "values" : [{"title":"Title 4","message":"another short one"}]},

{ "values" : [{"title":"Title 5","message":"and another
- longish
- one here"}]},

答案 1 :(得分:1)

如果你想使用sed

,你可以使用这个烂摊子
:1
/\n[^\n]*:::::/!{
   $!{
   N
   b1
   }
}
h
s/\n[^\n]*:::::[^\n]*$//
s/\(.*\):::::\(.*[^\n]\)\n\?/{ "values" : [{"title":"\1","message":"\2"}]},/
p
$!{
   x
   s/.*\n//
   b1
}
d

答案 2 :(得分:1)

仅使用sed变得非常神秘,但这是我能形成的最简单的1-liner:

$ cat file
Title 1:::::some message

Title 2:::::another message

Title 3:::::this time

- a longer
- message
- here

Title 4:::::another short one

Title 5:::::and another

- longish
- one here
$ sed -r '/^Title\s*[0-9]+/ {s/^(Title\s*[0-9]+):::::(.*)$/"}]}\n{ "values" : [{"title":"\1","message":"\2/}; $a"}]}' file | sed -n -r '1!{/^$/!p}'
{ "values" : [{"title":"Title 1","message":"some message
"}]}
{ "values" : [{"title":"Title 2","message":"another message
"}]}
{ "values" : [{"title":"Title 3","message":"this time
- a longer
- message
- here
"}]}
{ "values" : [{"title":"Title 4","message":"another short one
"}]}
{ "values" : [{"title":"Title 5","message":"and another
- longish
- one here
"}]}
$