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

9

Я хочу заменить все пары квадратных скобок в файле, например,[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.
The pairs only occur on individual lines, never across multiple lines. Sometimes there might be more than one pair on a single line, but they are never nested. If a bracket is found alone on a line, without a pair, then it should not be changed.

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

Ваш Ответ

4   ответа
4

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

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

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

The \[ is matching a square bracket. Since [ is a valid magic regular expression character, the backslash means to match the literal character. The (...) is a capture group. It captures the part of the regular expression I want. I can have many capture groups, and in sed I can reference them as \1, \2, etc. Inside the capture group \(...\). I have [^]]*. The [^...] syntax means any character but. The [^]] means any character but a closing brace. The * means zero or more of the preceding. That means I am capturing zero or more characters that are not closing square braces. The \] means the closing square bracket

Давайте посмотрим на строкуthis is [some] more [text]

In #1 above, I capture the first open square bracket in front of the word some. However, it's not in a capture group. This is the first character I'm going to substitute. I now start a capture group. I am capturing according to 3.2 and 3.3 above, starting with the letter s in some as many characters as possible that are not closing square brackets. This means I am matching [some, but only capturing some. In #4, I have ended my capture group. I've matched for substitution purposes [some and now I'm matching on the last closing square bracket. That means I'm matching [some]. Note that regular expressions are normally greedy. I'll explain below why this is important. Now, I can match the replacement string. This is much easier. It's \\macro(\1). The \1 is replaced by my capture group. The \\ is just a backslash. Thus, I'll replace [some] with \macro{some}.

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

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

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

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

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

Незначительное исправление ... Отредактировал мой ответ. На маленьком экране иногда трудно увидеть разницу между( а также{.
Прекрасное объяснение! Однако замена должна быть окружена\macro{...}
10

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

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

2

[a-z, A-Z and space] и заменяет его\macro{<whatever was between the []>}

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

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

Это может быть правильным для предоставленных тестовых данных, но[^]]* лучше подходит.

Похожие вопросы