Замена скобок на квадратные скобки в математических выражениях, использование обратных ссылок в sed

И для развлечения с paste:

paste -d'|,' <(seq 31) <(seq 31) /dev/null
0
05.10.2018, 09:57
1 ответ

Если вы просто хотите заменить все (на [и )на ], то обратные ссылки не нужны. Простой trсделает эту работу:

$ tr '()' '[]' <file
[[23 + 5][23 + 5]]
11 x [2+1] = 11 x 3 = 33
3x[5+2]

или с sed,

$ sed 'y/()/[]/' <file
[[23 + 5][23 + 5]]
11 x [2+1] = 11 x 3 = 33
3x[5+2]

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

$ sed -E -e ':loop' -e 's/\(([^()]+)\)/[\1]/; tloop' <file
[[23 + 5][23 + 5]]
11 x [2+1] = 11 x 3 = 33
3x[5+2]

Здесь мы сначала определяем метку loop, а затем выполняем нашу замену. Если подстановка что-то сделала, то мы возвращаемся к метке loop. Нам нужно сделать это таким образом, потому что использование s/.../.../gне найдет перекрывающихся совпадений, а перекрывающиеся совпадения будут, как только появятся вложенные скобки.

Подстановка s/\(([^()]+)\)/[\1]/найдет любую не-пустую строку внутри круглых скобок, которая не содержит (или ), и заменит ее самой собой, но окружающие круглые скобки будут заменены квадратными скобками.

Для входной линии

((23 + 5)(23 + 5))

это заставит sedвыполнить замену четыре раза:

  1. ([23 + 5](23 + 5)), заменяется первая внутренняя скобка.
  2. ([23 + 5][23 + 5]), затем второй внутренний.
  3. [[23 + 5][23 + 5]], затем внешний.
  4. Последняя подстановка ничего не сделает, и цикл завершится.

Использование флага gв конце выражения подстановки приведет к тому, что первые два шага, описанные выше, будут выполняться в одной подстановке, поскольку они не перекрываются -.


С эквивалентными базовыми регулярными выражениями (в приведенном выше примере используется расширенное регулярное выражение для удобства чтения):

sed -e ':loop' -e 's/(\([^()][^()]*\))/[\1]/; tloop' <file
9
28.01.2020, 02:14

Теги

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