Getting text from between a specific pair delimiters using sed
I am using sed for the first time so it might not even be the right tool for the job but after extensive googling it seems to be what would do the job. My problem is that i have a data file from which I need to extract some data and discard the rest.
Sample data
#Ranger (62:0)
Device pose: (0, 0, 0), (0, 0, 0)
Device size: (0, 0, 0)
Configuration:
Minimum angle: 0 Maximum angle: 0 Angular resolution: 0
Minimum range: 0 Maximum range: 0Range resolution: 0
Scanning frequency: 0
682 range readings:
[0.529, 0.524, 0.511, 0.506, 0.505, 0.505, 0.505, 0.505, 0.505, 0.503, 0.495, 0.483, 0.471, 0.469, 0.469, 0.469, 0.469, 0.465, 0.458, 0.458, 0.454, 0.454, 0.454, 0.45, 0.443, 0.442, 0.442, 0.443]
#Ranger (62:0)
Device pose: (0, 0, 0), (0, 0, 0)
Device size: (0, 0, 0)
Configuration:
Minimum angle: 0 Maximum angle: 0 Angular resolution: 0
Minimum range: 0 Maximum range: 0Range resolution: 0
Scanning frequency: 0
682 range readings:
[0.529, 0.524, 0.511, 0.506, 0.505, 0.505, 0.505, 0.505, 0.5开发者_StackOverflow中文版05, 0.503, 0.495, 0.483, 0.471, 0.469, 0.469, 0.469, 0.469, 0.465, 0.458, 0.458, 0.454, 0.454, 0.454, 0.45, 0.443, 0.442, 0.442, 0.443]
This pattern is repeated quite a few number of times. The data that I want is between the [ and ]. I want all the data between all the [ ] pairs. I have tried a few sed scripts including one that was sent as a solution to a very similar problem but to no avail. The script
sed -n -e '/\[[^]]/s/^[^[]*\[\([^]]*\)].*$/\1/p' <a.txt >b.txt
produces an empty b.txt. Then I tried
sed -e '1s/#/<rem>\n&/g' -e 's/\]/\n<rem>/g' -e 's/\[/<\/rem>\n/g' -e '/^$/d' -e 's/[ ]*//g' <a.txt > b.txt
Which produces nice delimited blocks of data that are surrounded by <rem>
and </rem>
tags like so
<rem>
#Ranger(62:0)
Devicepose:(0,0,0),(0,0,0)
Devicesize:(0,0,0)
Configuration:
Minimumangle:0 Maximumangle:0 Angularresolution:0
Minimumrange:0 Maximumrange:0Rangeresolution:0
Scanningfrequency:0
682rangereadings:
</rem>
0.529,0.524,0.511,0.506,0.505,0.505,0.505,0.505,0.505,0.503,0.495,0.483,0.471,0.469,0.469,0.469,0.469,0.465,0.458,0.458,0.454,0.454,0.454,0.45,0.443,0.442,0.442,0.443,0.451,0.459,0.459
<rem>
#Ranger(62:0)
Devicepose:(0,0,0),(0,0,0)
Devicesize:(0,0,0)
After this when I try
sed -e '/<rem>/,/<\/rem>/d' <b.txt >c.txt
I get
#Ranger(62:0)
Devicepose:(0,0,0),(0,0,0)
Devicesize:(0,0,0)
Configuration:
Minimumangle:0 Maximumangle:0 Angularresolution:0
Minimumrange:0 Maximumrange:0Rangeresolution:0
Scanningfrequency:0
682rangereadings:
#Ranger(62:0)
Devicepose:(0,0,0),(0,0,0)
Devicesize:(0,0,0)
Exactly the opposite of what I am trying to achieve. Can someone please help? Sorry for the long explanation.
Maybe this is what you want:
sed -nr 's/\s*\[([^\]+)\]/\1/p'
This can be done easily with grep
:
user@machine:~/tmp$ grep '\[' data
[0.529, 0.524, 0.511, 0.506, 0.505, 0.505, 0.505, 0.505, 0.505, 0.503, 0.495, 0.483, 0.471, 0.469, 0.469, 0.469, 0.469, 0.465, 0.458, 0.458, 0.454, 0.454, 0.454, 0.45, 0.443, 0.442, 0.442, 0.443]
[0.529, 0.524, 0.511, 0.506, 0.505, 0.505, 0.505, 0.505, 0.505, 0.503, 0.495, 0.483, 0.471, 0.469, 0.469, 0.469, 0.469, 0.465, 0.458, 0.458, 0.454, 0.454, 0.454, 0.45, 0.443, 0.442, 0.442, 0.443]
If you want to store the output in a new file, just redirect:
user@machine:~/tmp$ grep '\[' data > extracted_values.dat
According to your data, it seems you only need to get those in []
and no other lines contain []
. Here are some other ways
$ awk '/\[/{ gsub(/\[|\]/,"");print}' file
its says search for [
and print the line, at the same time removing the brackets (if you need the brackets , remove the gsub
statement
$ ruby -ne 'print if /\[/' file
or
$ ruby -ne 'puts $_.scan(/\[(.*?)\]/) if /\[/' file #no brackets
0.529, 0.524, 0.511, 0.506, 0.505, 0.505, 0.505, 0.505, 0.505, 0.503, 0.495, 0.483, 0.471, 0.469, 0.469, 0.469, 0.469, 0.465, 0.458, 0.458, 0.454, 0.454, 0.454, 0.45, 0.443, 0.442, 0.442, 0.443
0.529, 0.524, 0.511, 0.506, 0.505, 0.505, 0.505, 0.505, 0.505, 0.503, 0.495, 0.483, 0.471, 0.469, 0.469, 0.469, 0.469, 0.465, 0.458, 0.458, 0.454, 0.454, 0.454, 0.45, 0.443, 0.442, 0.442, 0.443
with grep
$ grep "\[" file
if you insist on sed
$ sed -n '/\[/p' file
精彩评论