Мне нужно обновить номер версии в файле. В файле есть одна строка, содержащая смысловую -номер версии примерно так:
foo.bar.blah.blub#10.6.1
Теперь я хочу найти префикс "blah.blub", чтобы определить правильную строку и заменить номер версии.
Я получил следующее, что явно не работает:
sed -i -e 's/^blah.blub#\d\.\d\.\d$/blah.blub'${VERSION}/$ README.MD
Sed использует базовые регулярные выражения по умолчанию, и большинство реализаций (, включая ту, которую вы используете GNU, )не понимают \d
. Кроме того, ваша строка не начинается с blah.blub
, поэтому ^
означает, что она никогда не будет совпадать. И разные другие вопросы.
Это должно делать то, что вам нужно:
sed -i -E "/blah\.blub#/s/#.*/#$VERSION/" README.MD
Это заменит текст после #
содержимым $VERSION
, но только если эта строка содержит blah.blub
. Теперь, достаточно ли это конкретно для работы с вашими данными, я понятия не имею, поскольку вы показали нам только одну эту строку.
-i
и \d
являются функциями perl
. Существуют sed
реализации, в которые добавлены одна или обе (, например функции )ast -open, но в любом случае ни одна из функций не входит в стандартную спецификацию команды sed
и не является переносимой.
Здесь можно использовать настоящую:
export VERSION
perl -pi -e 's/^([\w.]*\.)?blah\.blub#\K\d+\.\d+\.\d+$/$ENV{VERSION}/' README.MD
Здесь разрешена необязательная последовательность из 0 или более слов символов или точек, заканчивающаяся точкой перед blah.bluh
, и разрешено более одной цифры в каждом из 3 компонентов исходного номера версии..
Мы также передаем строку новой версии через переменную среды, а не в выражение кода, что делает ее более безопасной (позволяет избежать уязвимости внедрения произвольного кода )и более надежно (позволяет использовать любой символ или даже байт значение в тексте новой версии ).