Как использовать группы захвата с помощью sed? - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь заменить текст в файле, используя sed, но у меня возникают проблемы.

sed -ir 's/(\$hello = )true/\1false/' /path/to/my/file.txt выдает ошибку sed: -e expression #1, char 27: invalid reference \1 on 's' command's RHS.

Я хочу замените $hello = true на $hello = false, поэтому, чтобы не вводить дважды $hello =, я хотел использовать группы захвата - что не работает.

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Вы не должны избегать скобок в расширенном режиме регулярных выражений, если это было ваше намерение с r в -ir, но на самом деле, если вы хотите обе опции -i и -r, то вы должны сохранить отделить их или использовать -ri вместо -ir, поскольку последний интерпретирует деталь после -i как необязательный резервный суффикс.

Из sed manual

Поскольку -i принимает необязательный аргумент, за ним не должны следовать другие короткие параметры:

sed -Ei '...' FILE

То же, что -E -i без суффикса резервной копии - FILE будет редактироваться на месте без создания резервной копии.

sed -iE '...' FILE

Это эквивалентно --in-place = E, создание FILEE в качестве резервной копии FILE

1 голос
/ 28 февраля 2020

Вы должны экранировать скобки с обратными слешами \(...\), чтобы использовать их в качестве группировки.

См. Часто задаваемые вопросы по SED , раздел "3.1.2. Экранирующие символы справа от "s ///" "имеет пример:

3.1.2. Экранирующие символы в правой части "s ///"

Правая часть (замещающая часть) в "s / find / replace /" почти всегда является строковым литералом, без интерполяции этих метасимволы:

  .   ^   $   [   ]   {   }   (   )  ?   +   *   |

Три вещи интерполированы : амперсанд (&), обратные ссылки и опции для специальных групп. Амперсанд на RHS заменяется на все выражение, сопоставленное на LHS. никогда нет никаких причин использовать группировку следующим образом:

  s/\(some-complex-regex\)/one two \1 three/

И далее в разделе «F. GNU sed v2.05 и более поздние версии»:

F. GNU sed v2.05 и более поздние версии

...

Недокументированный ключ -r:

Начиная с версии 3.02, GNU sed имеет недокументированный ключ -r (недокументированный до версия 4.0), активируя Расширенные Регулярные выражения следующим образом:

 ?      -  0 or 1 occurrence of previous character
 +      -  1 or more occurrences of previous character
 |      -  matches the string on either side, e.g., foo|bar
 (...)  -  enable grouping without backslash
 {...}  -  enable interval expression without backslash

Когда используется ключ -r (mnemoni c: «регулярное выражение»), добавьте к этим символам обратный символ sh. чтобы отключить специальное значение.


Для документирования синтаксиса регулярного выражения, используемого в (GNU) sed, см. Обзор основы c синтаксис регулярного выражения

5.3 Обзор базового c синтаксиса регулярных выражений

...

\ (regexp \)

Группирует внутреннее регулярное выражение в целом, это используется для:

  • Применения постфиксных операторов, например (abcd) *: это будет искать ноль или более целых последовательностей 'abcd', тогда как abcd * будет искать «abc», за которым следует ноль или более вхождений «d». Обратите внимание, что поддержка (abcd) * требуется POSIX 1003.1-2001, но многие реализации не-GNU не поддерживают ее, и, следовательно, она не является универсально переносимой.
  • Используйте обратные ссылки (см. Ниже).
...