Форумы
Kalina LUG :: Форумы :: Основной :: Трюки и фичи
 
<< Предыдущая тема | Следующая тема >>
Многострочный поиск при помощи sed [РЕШЕНО]
Модераторы: kalina, sanitar, NaTty, COMRADE_ARTYOM, variable, Solaris, az, Andreyf1
Автор Добавил
Kross
Птн Авг 12 2011, 21:44
ID пользователя #284
Зарегистрирован: Птн Авг 12 2011, 21:14

Сообщений: 4
Друзья, здравствуйте
Я новичок потому не судите строго за мой вопрос если он покажется вам ламерским. Итак суть такова
есть xtml файл, который необходимо пропарсить, но парсить его необходимо блоками, другими словами мне необходимо оставить лишь те блоки или параграфы (содержащие несколько строк), которые содержат определенные выражения.
Я для работы с блоками использовал парсинг при помощи sed и следующую конструкцию:
begin="<start>"
end="</\stop>"
regex="string"
sed -e '/$begin.*$regex/,/$end/!d'

где соответственно begin- выражение соотвествующее началу блока,
end_block- выражение соотвествующее концу блока и
regex- строка которую я ищу в блоке.

Если мне необходимо найти несколько соотвествий, то я лишь добавляю еще такую же подобную конструкцию через "-e", тем самым получаю логическое И.
begin="<start>"
end="</\stop>"
regex="string"
regex2="string2"
sed -e '/$begin.*$regex1/,/$end/d!' -e '/$begin.*$regex2/,/$end/d!'

(такая кстати конструкция быстрее работает чем просто несколько седов подряд) Если кто может подсказать более элегантное решение конструкции логического И при работе с блоками - пожалуйста дайте знать.
Так вот все это работает если искомая строка находится на той же строке что и начало блока, однако если искомая строка находится на другой строке, то поиск не срабатывает. Не помогают конструкции с \n и c \r.
Опция "m" или "М", которые вроде как должны решать данный вопрос на Tuxbox не работают, так как sh упрощен донельзя, bash отсутствует.
(Tuxbox это упрощенный интерпретатор, в частности для цифровых ресиверов для приема спутниковых сигналов.)

Если у кого есть мысли на эту тему пожалуйста дайте знать. Использование других инструментов так же приветсвуется, типа awk, однако я им не пользуюсь здесь, так как проц очень слабенький и на седе все делается долго, а на аваке будет еще дольше.
Еще раз прошу не пинать сильно, потому как я новичок в Unix среде.

[ Редактирование Втр Авг 23 2011, 16:22 ]
Наверх
Kross
Сбт Авг 13 2011, 01:13
ID пользователя #284
Зарегистрирован: Птн Авг 12 2011, 21:14

Сообщений: 4
Друзья, я нашел ответ, все работает на ура, может кому пригодится:
#!/bin/sh          # или bash
source="./my_file" # Файл в котором осуществляем поиск блоков
begin="<start>"    # Начало блока
end="</\stop>"     # Конец блока
regex1="string1"   # Первое искомое выражение, в любой строке блока
regex2="string2"   # Второе искомое выражение, в любой строке блока
# Поиск блока и вывод его на экран
# Логическое ИЛИ
cat $source | \
sed  -ne :t -e '/$begin/,/$end/{/$end/!{$!{N;bt }}/$regex1/p;/$regex2/p;}'
# или логическое И
cat $source | \
sed  -ne :t -e '/$begin/,/$end/{/$end/!{$!{N;bt }}/$regex1.*$regex2/p;}'

'ИЛИ', значит, что необходимо вывести блоки которые содержат либо первое искомое выражение либо второе. Если необходимо найти только одно, то один из блоков регулярного выражения убираем.
'И' значит что блок содержит и первое искомое выражение и второе одновременно.

ВАЖНО!!! чтобы в выражении
{N;bt }
был пробел после "t", если все писать в одну строку, а не в несколько строк, как в примере на который я ниже ссылаюсь.

Я здесь немного модернизировал скрипт по удалению всех блоков в которых была найдена заданная строка, см. здесь: sed.sourceforge.net
В примере так же рассмотрен случай замены на несколько различных строк.
Удачи всем!

[ Редактирование Сбт Авг 13 2011, 09:45 ]
Наверх
 

Перейти:     Наверх

Транслировать сообщения этой темы: rss 0.92 Транслировать сообщения этой темы: rss 2.0 Транслировать сообщения этой темы: RDF
Powered by e107 Forum System