Регулярное выражение для замены чисел не работает с 'sed'

Префикс часто приписывают проблемам с пустыми строками, но это не причина. Проблема очень проста, :расширение переменной может быть одним из testоператоров, внезапно превращающих бинарную проверку на равенство в другое выражение.

Недавние реализации команды на большинстве платформ избегают ловушки с просмотром -вперед в синтаксическом анализаторе выражений, не позволяя синтаксическому анализатору распознавать первый операнд бинарного оператора как что-либо, кроме операнда, до тех пор, пока имеется достаточно tokens to быть бинарным оператором, конечно:

% a=-n
% /bin/test "$a" = -n ; echo $?
0
% /bin/test "$a" = ; echo $?
0
% /bin/test x"$a" = ; echo $?
test: =: argument expected
2
% a='('
% /bin/test "$a" = "(" ; echo $?
0
% /bin/test "$a" = ; echo $?
test: closing paren expected
2
%
0
12.03.2021, 10:43
1 ответ

Вы используете квантификатор +из набора синтаксиса Расширенное регулярное выражение , но sedпо умолчанию использует базовые регулярные выражения. Итак, вам нужно включить ERE, добавив флаг -E:

sed -E 's/[0-9][0-9]+/9999/' file.cpp

или используйте соответствующую конструкцию BRE

sed 's/[0-9]\{2,\}/9999/' file.cpp

, который является более переносимым (, как отметил @Stéphane Chazelas ).


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

if (counter==(1000)) {

, я бы рекомендовал добавить подходящий спецификатор адреса , чтобы сделать сопоставление более конкретным:

sed '/if (counter==([0-9]\{2,\}))/s/[0-9]\{2,\}/9999/' file.cpp 

Таким образом, подстановка будет выполняться только в строках, соответствующих if (counter==(two-or-more-digit-number)).

Опция gкажется ненужной, потому что в вашем примере ввода есть только одна такая группа цифр в строке.


Чтобы модифицировать файл напрямую, большинство sedреализаций теперь понимают флаг -iдля модификаций «в -месте». Опять же, как правильно заметил @Stéphane Chazelas, если вы используете его в сочетании с другими флагами, обязательно сделайте правильный порядок, так как -iожидает суффикс для создания файла резервной копии (, который может быть оставлен пустым в GNU. sed, но требуется в реализациях FreeBSD/MacOS):

  • sed -i '' -E 's/.../.../'будет работать на FreeBSDsed
  • sed -i -E 's/.../.../'или sed -Ei 's/.../.../'будут работать на GNUsed
  • sed -iE 's/.../.../'не будет работать, так как Eбудет считаться резервным суффиксом.
3
18.03.2021, 22:25

Теги

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