开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜