2013-01-09 2 views
4

я отправил this question и кто-то ответил с этимНужна помощь с пониманием это регулярное выражение в SED

sed '/^void.*{$/!b;:a;/\n}$/bb;$!{N;ba};:b;s/\n/&test1&/;s/\(.*\n\)\(.*\n\)/\1test2\n\2/' file

Я новичок в СЭД и регулярное выражение, и я не в состоянии понять, что функция каждой части.

Я попытаюсь объяснить, что я понял, и вы, ребята, можете заполнить недостающие вещи. я буду идти по посимвольно

  1. ^void.*{$ - Это означает, что все, что начинается с void и заканчивается {
  2. /!b; я не понял, что это делает. Сейчас b для branching. что / там делает
  3. :a; для изготовления ярлыку a
  4. /\n Опять не понял / там
  5. }$, который заканчивается }
  6. /bb я не понимаю
  7. $! означает, что если не закончится файла
  8. {N; не получил то, что он означает, N означает скопировать следующую строку в буфер, но получил {
  9. :b Не понял. б для ветви, но не знаю, что его там делает 10. s/\n/&test1&/ я думаю, его замена \ п с \ntest1\n, но не уверен
  10. s/\(.*\n\)\(.*\n\)/\1test2\n\2/ Dont получить это, а
+0

Похоже, что человек, который ответил на ваш вопрос, добавил [объяснение] (http://stackoverflow.com/a/14215634/1938444). – mgamba

+0

он добавил экспансию в группы, и я даже не понимаю этого. я хотел понять по характеру по характеру – user175386049

+0

sed - отличный инструмент для простых замещений на одной строке, но для чего-то еще вы должны использовать awk вместо этого. Я использую sed в течение 30 лет и даже не могу догадаться о том, что делает ваша команда. Если вы обнаружите, что используете больше команд «s» и «g», вы, вероятно, используете неправильный инструмент, поэтому не тратьте время на это, просто получите awk-решение, и оно будет более четким, простым и легче улучшить в будущем. –

ответ

2

Вы можете объединять несколько выражений СЭД вместе с ; характером. Вот посмотрите на каждый отдельно.

Первое выражение, /^void.*{$/!b, имеет выражение-разделитель между разделителем /. Это соответствует:

^ - начало линии

void - за которым следуют символы "недействительным"

.* - а затем что-нибудь

{ - а затем левая фигурная

$ - далее следует конец линии

Модификатор в этом первом выражении, !b, означает, что если совпадение не соответствует, прервите оценку sed.

Выражение :a является ярлыком. Он используется с функцией goto-like sed, называемой ветвлением. Мы увидим, как метки используются в следующем выражении.

выражение /\n}$/bb матчи:

\n - символ новой строки

} - а затем правой фигурные

$ - а затем к концу линии

Модификатор bb означает, что если вы найдете совпадение «ветвь» на метке b. Метка b определяется в более позднем выражении как :b.

Выражение $!{N;ba} должно рассматриваться как одно, хотя оно имеет ; посередине. Колонки в этом случае представляют собой последовательность команд, которые должны выполняться вместе.

$! - если это не конец ввода

{ - начать группу команд (в данном случае, есть два из них)

N - читать еще одну линию, молча

ba - ответвление на метку a

} - конечная группа команд

Следующая метка :b, которую мы ударим, когда мы сопоставим один } на отдельной строке, используя выражение /\n}$/bb.

Наконец, есть два шаблона замены, которые являются довольно стандартным регулярным выражением. s перед выражением по существу означает s/find_this/replace_it_with_this/. В случае s/\n/&test1&/, мы имеем:

\n - найти строку

/ - и заменить его

& - вещь, которая была подобрана в первом выражении (в этом случае символ новой строки)

test1 - слово test1

& - и снова вещь, которая была подобрана

Таким образом, в основном s/\n/&test1&/ означает замену следующего \n на \ntest1\n.

Последнее выражение похоже, но вводит что-то называемое захватами. Захваты позволяют вам по-прежнему соответствовать всем, но сохраняйте все между \( и \) для использования в заменяющей части выражения. Например, s/a\(b\)c\(d\)e/\1 \2/ выводит b d, если задана входная строка abcde. В этом примере \1 и \2 заменяются вещами, которые захватываются в экранированных парнах, b и d, соответственно.

s - это модель замещения:

/ - найти

\( - и поместить в переменную \1 замены

. - ничего

* - и любое его количество

\n - включая первый символ новой строки вы столкнетесь

\) - (конец захвата для \1)

\( - и поместить в переменную \2 замены

. - ничего

* - и любая его сумма

\n - в том числе первого символа новой строки вы столкнетесь

\) - (конец захвата для \2)

/ - и заменить все это с

\1 - первая вещь, захваченной,

test2\n - test2 \ n,

\2 - и вторая вещь снята.

+0

Спасибо, dude u rock, и действительно очистил мои недостающие сомнения – user175386049

2

Этот термин:

/^void.*{$/!b 

означает соответствие ^void.*{$, а косые черты - это регулярные выражения, окружающие регулярное выражение. Таким образом, вы получаете /^void.*{$/. Если восклицательный знак следует за выражением соответствия, как в /regex/!, тогда это означает следующую команду, если regex выполняет not. Следующая команда: b, которая является ветвью. Который, без названия ярлыка, ветвится в конце скрипта. Таким образом, в целом это выражение пытается совместить ^void.*{$ (т. Е. Строка, начинающаяся с void и заканчивающаяся {) и перескакивает (b) остальную часть скрипта в случае сбоя совпадения (!).

Эта вещь:

:a;/\n}$/bb;$!{N;ba}; 

начинает метку :a; и пытается соответствовать \n}$ (перевод строки и один } на линии), который снова заключен в /regex/. По матчу он разветвляет (b) на ярлык b (следовательно, /regex/bb). Если это не конец ввода ($!), затем прочитайте строку N и вернитесь к метке a (ba). Здесь фигурная пара (то есть {commands}) создает блок.Этот блок выполнен в целом, если $! истинно, что означает, что есть больше ввода. Так $!{N;ba} просто означает:

If not end of input: 
begin 
    real line 
    jump to label a 
end 
+0

Спасибо, приятель, теперь я получаю это – user175386049

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