Как заменить парные квадратные скобки другим синтаксисом на sed?

Я хочу, чтобы заменить все пары квадратных скобок в файле, например, [some text] С macro{some text}, например:

This is some [text].
This [line] has [some more] text.

это будет:

This is some macro{text}.
This macro{line} has macro{some more} text.
  • пары встречаются только на отдельных линиях, никогда не через несколько строк.
  • иногда в одной строке может быть более одной пары, но они никогда не вложены.
  • если скобка находится одна на линии, без пары, то она не должна быть изменена.

как может Я заменяю эти пары скобок этим кодом?

4 ответов


sed -e 's/\[\([^]]*\)\]/\macro{}/g' file.txt

Это ищет открывающую скобку, любое количество явно не закрывающихся скобок, а затем закрывающую скобку. Группа захватывается родителями и вставляется в выражение замены.


это заняло немного времени, но здесь:

sed -i.bkup  's/\[\([^]]*\)\]/\macro{}/g' test.txt

посмотрим, смогу ли я объяснить это регулярное выражение:

  1. на \[ соответствует квадратной скобке. С [ является допустимым символом регулярного выражения magic, обратная косая черта означает соответствие буквальному символу.
  2. у (...) является группой захвата. Он захватывает часть регулярного выражения, которое я хочу. У меня может быть много групп захвата, и в sed Я могу ссылаться на них, как , , etc.
  3. внутри группы захвата \(...\). У меня [^]]*.
    1. на [^...] синтаксис означает любой символ, но.
    2. на [^]] означает любой символ, кроме закрывающей скобки.
    3. на * означает ноль или более предшествующих. Это означает, что я захватываю ноль или более символов, которые не закрывают квадратные скобки.
  4. на \] означает закрывающую квадратную скобку

давайте посмотрите на линию это [некоторые] больше [текст]

  • в #1 выше я захватываю первую открытую квадратную скобку перед словом некоторые. Однако это не группа захвата. Это первый персонаж, которого я собираюсь заменить.
  • теперь я запускаю группу захвата. Я захватываю в соответствии с 3.2 и 3.3 выше, начиная с буквы s на некоторые как можно больше символов, которые не закрывают квадрат скобки. Это означает, что я соответствую [some, но только захватив some.
  • в #4 я закончил свою группу захвата. Я сопоставил для целей замены [some и теперь я соответствую на последней заключительной квадратной скобке. Это означает, что я соответствую [some]. Обратите внимание, что регулярные выражения обычно жадны. Я объясню ниже, почему это важно.
  • теперь я могу сопоставить строку замены. Это гораздо проще. Это \macro(). The заменяется на my группа захвата. The \ это просто обратная косая черта. Таким образом, я заменю [some] С \macro{some}.

было бы намного проще, если бы мне гарантировали один набор квадратных скобок в каждой строке. Тогда я мог бы сделать вот что:--34-->

sed -i.bkup 's/\[\(.*\)\]/\macro()/g'

группа захвата теперь говорит что-нибудь между квадратными скобками. Однако проблема в том, что регулярные выражения жадны, это означает, что я бы соответствовал из s на some до самого финала t в тексте. "X" ниже показывает группу захвата. The [ и ] показать квадратные скобки, которые я сопоставляю:

 this is [some] more [text]
         [xxxxxxxxxxxxxxxx]

это стало сложнее, потому что я должен был соответствовать символам, которые имели особое значение для регулярных выражений, поэтому мы видим много обратной косой черты. Кроме того, мне пришлось учитывать жадность регулярного выражения, которая получила симпатичную, не совпадающую строку [^]]* матч ничего не закрывающей скобкой. Добавить в квадратные скобки до и после \[[^]]*\], и не забудь \(...\) группа захвата: \[\([^]]*\)\]и вы получаете один большой беспорядок регулярного выражения.


использовать группы

sed 's|\[\([^]]*\)\]|\macro{}|g' file

следующее выражение соответствует шаблону [a-z, A-Z and space] и заменяет его \macro{<whatever was between the []>}

sed -e 's/\[\([a-zA-Z ]*\)\]/\macro{}/g'

В выражение \( ... \) сформируйте группу соответствия, на которую можно ссылаться позже в подстановке как