Получение текста между определенной парой разделителей с помощью sed - PullRequest
1 голос
/ 02 апреля 2011

Я впервые использую sed, так что это может быть даже не самый подходящий инструмент для работы, но после интенсивного поиска в Google, похоже, именно это и сделает работу. Моя проблема в том, что у меня есть файл данных, из которого мне нужно извлечь некоторые данные и отбросить остальные.

Пример данных

    #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.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]

Этот паттерн повторяется довольно много раз. Данные, которые я хочу, находятся между [и]. Я хочу, чтобы все данные были между всеми парами []. Я попробовал несколько сценариев sed, в том числе тот, который был отправлен как решение очень похожей проблемы, но безрезультатно. Сценарий

sed -n -e '/\[[^]]/s/^[^[]*\[\([^]]*\)].*$/\1/p' <a.txt >b.txt

создает пустой b.txt. Тогда я попробовал

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

Создает блоки данных с разделителями, которые окружены тегами <rem> и </rem>, например

<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)

После этого, когда я пытаюсь

sed -e '/<rem>/,/<\/rem>/d' <b.txt >c.txt

Я получаю

#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)

Совершенно противоположное тому, чего я пытаюсь достичь. Может кто-нибудь, пожалуйста, помогите? Извините за длинное объяснение.

Ответы [ 3 ]

2 голосов
/ 02 апреля 2011

Может быть, это то, что вы хотите:

sed -nr 's/\s*\[([^\]+)\]/\1/p'
1 голос
/ 02 апреля 2011

Судя по вашим данным, вам нужно получить их только в [], и никакие другие строки не содержат []. Вот еще несколько способов

$ awk '/\[/{ gsub(/\[|\]/,"");print}' file

говорит, что ищет [ и печатает строку, одновременно снимая скобки (если вам нужны скобки, удалите оператор gsub

$ ruby -ne 'print if /\[/' file 

или

$ 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

с grep

$ grep "\[" file

если вы настаиваете на sed

$ sed -n '/\[/p' file
1 голос
/ 02 апреля 2011

Это можно легко сделать с помощью 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]

Если вы хотите сохранить вывод в новом файле, просто перенаправьте:

user@machine:~/tmp$ grep '\[' data > extracted_values.dat
...