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:
{ "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
. 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
?
You can use 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
: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:
$ 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
"}]}
$
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.