简体   繁体   English

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

[英]How do I replace strings on optional multiple-lines in sed?

I have the following string: 我有以下字符串:

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

I am trying to replace the above with sed to have the following format: 我试图用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"}]},

I know this may be easier with Perl but I'd specifically like to know how to do it with sed . 我知道Perl可能会更容易,但我特别想知道如何用sed做到这一点。 As you can see, it may or may not be a multi-line match. 如您所见,它可能是也可能不是多行匹配。

So far I have: 到目前为止,我有:

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

Which results in the following: 其结果如下:

{ "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

What's the best way to accomplish this properly with sed ? 使用sed正确完成此操作的最佳方法是什么?

You can use awk: 你可以使用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

Output: 输出:

{ "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"}]},

You can use this mess if you want to use sed 如果你想使用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

It gets very cryptic using sed only but this is the simplest 1-liner I could form: 它只使用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
"}]}
$

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM