2014-11-09 2 views
1

У меня есть следующий код:Замена блока текста с отступами по СЭДУ

echo -e ' aaa\nddd\nddd\n bbb' | sed -re ':x; N; $!b x; s/(^|\n)(\s*)(aaa)\n(.*?)\n\2(bbb)(\n|$)/\1\2\3\n\2ccc\n\2\5\6/g' 

Этот код заменяет все между ааа & БББОМ с сссом. Кроме того, она использует те же отступы он находит:

fff 
    aaa 
    ddd 
    ddd 
    bbb 
fff 

будут обработаны в

fff 
    aaa 
    ccc 
    bbb 
fff 

Но есть проблема. Я не могу портировать его использовать свои переменные:

sed -ire ":x; N; $!b x; [email protected](^|\n)(\s*)(${START})\n(.*?)\n\2(${STOPSEQREG})(\n|$)@\1\2\3\n\2${ENUMARRAY[$i]}\n\2\5\[email protected]" $f 

START, STOPSEQREG & ENUMARRAY [я] содержит /, *, пробелы:,;, + и -. Также элементы массива содержат \ n. Символы/& * экранируются с помощью \.

Ошибка, показываемая при запуске «Плохая обратная связь».

Может кто-нибудь, пожалуйста, помогите мне?

Заранее спасибо.

P.S. Примеры переменных:

START: /* R+ Testy */ (with escaped/& *) 
STOPSEQREG: /* R- */ (with escaped/& *) 
ENUARRAY[i]: case AAA:\n break; 
+0

Вы можете предоставить сценарий, в котором вы используете 'sed' с различными вариантами. – nu11p01n73R

+0

Здесь полный скрипт: http://paste.org.ru/?6iwb4l Вот тестовые файлы: источник: http://paste.org.ru/?yu4yiq и цель: http://paste.org.ru/?tlzelb –

ответ

1

Несколько вещей, я обнаружил:

  • Вы должны процитировать $ S внутри СЕПГ сценария в BASH, вероятно, получить там первую и интерпретировать их как пустые переменные. Поэтому вместо $!b и (\n|$) попробуйте \$!b и (\n|\$).
  • Существует потенциал для упрощения этого регулярного выражения - например, не может (.*?) быть уменьшен до (.+)?
  • ... но самое главное, не использовать -ire с (GNU) sed. r потребляется в качестве параметра -i (резервное копирование), поэтому ваше регулярное выражение рассматривается как базовое, для которого необходимо, чтобы каждая скобка была экранирована и не поддерживала \s и т. Д. Именно поэтому sed видит, что нет захваченных групп , Вместо этого используйте -i -re. См. GNU SED manual, и этот вопрос тоже: In-place sed command not working.

Генеральной сторона: для чего-то этот комплекса, я лично всегда смотрю на язык с приличными регулярными выражениями и поддержкой оболочки, например, Python/Perl/Ruby/Groovy и т. Д. Это позволяет избежать BASH (или другой оболочки)/SED, цитируя hell quirks and issues, позволяет тестировать/отлаживать и регистрировать единицу/интеграцию, но, очевидно, иногда приводит свой собственный багаж или isn К сожалению, всегда возможно.

+0

1) Что следует использовать вместо aire? 2) Я попробовал обратные символы с символом «минус» или использовать «как»; "'$'"! b', но он все еще не работает. –

+0

К сожалению, да, наверное, добавил, что ... см. Мой обновленный ответ! (в кратком использовании '-i -re') – declension

+0

Вот какой код выглядит прямо сейчас:' sed -i -re ': x; N; \ $! bx; s @ (^ | \ n) (\ s *) ($ {START}) \ п (+) \ п \ 2 ($ {STOPSEQREG}) (\ п |. \ $) @ \ 1 \ 2 \ 3 \ п \ 2 $ {ENUMARRAY [$ я]} \ n \ 2 \ 5 \ 6 @ g "$ f' Но этот код ничего не заменяет. Полный скрипт: http://paste.org.ru/?6ucf7g –

Смежные вопросы