Зачем sed добавлять 0 в мою замену?

пример тестового файла с многострочным

eval_config: {
  Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.

The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.
}

Может попробовать

sed ':again;$!N;$!b again; s/eval_config: {[^}]*}/\eval_config: {replacement text}/g'  testfile
-1
05.05.2020, 21:43
3 ответа

[0-90-9]соответствует одному символу, который может быть любой цифрой. Вы имели в виду, что [0-9][0-9]соответствует ровно двум цифрам. В обеих попытках последняя цифра 5.6.100не совпадала с регулярным выражением, поэтому она присутствует в выводе без изменений.

Другая потенциальная проблема заключается в том, что .является специальным символом в регулярных выражениях :он соответствует любому символу. Например, [0-9].[0-9].[0-9][0-9]соответствует 123.45или 1a2b34. Используйте \.для сопоставления точки :с обратной косой чертой перед специальным символом, который делает его неспециальным -.

Кроме того, номер версии может состоять из большего или меньшего количества цифр. Используйте [0-9.]*для сопоставления любого количества точек или цифр.(.не является специальным символом, если он заключен в скобки. )Точнее, [0-9.]*соответствует максимально длинной последовательности точек и цифр, поэтому она будет соответствовать всем им. Используйте [0-9][0-9.]*, если вы хотите, чтобы в начале была хотя бы одна цифра.

sed 's:VERSION=[0-9][0-9.]*:VERSION=5.6.10:g'
4
28.04.2021, 23:16

Решение найдено добавлением точки. Эта работа для 5.5.10, 6.4.20, 3.2.20 и т. д.

sed s:VERSION=[0-9].[0-9].[0-9].:VERSION=5.6.10:g 

Но не для 1.2.3 4.5.1 3.2.9 Для этих пар эта линия работает нормально

sed s:VERSION=[0-9].[0-9].*.:VERSION=5.6.10:g 
0
28.04.2021, 23:16

Предполагая, что вы правильно цитируете свое выражение sed, чтобы оболочка не расширяла его как шаблон подстановки имени файла, ваша команда

sed 's:VERSION=[0-9].[0-9].[0-90-9]:VERSION=5.6.10:g'

превратит строку VERSION=5.4.38в VERSION=5.6.108(, а не вVERSION=5.6.100). Это происходит потому, что [0-90-9]соответствует одному символу . Таким образом, он заменяет VERSION=5.4.3на VERSION=5.6.10, оставляя замыкающий 8в покое.

Другие странности в вашей sedподстановке включают отсутствие экранирования точек (они будут соответствовать любому одиночному символу )и использование /gв конце, даже если вы не ожидаете совпадения более чем с одной строкой любая одна линия, насколько я могу судить.

Чтобы заменить шаблон в форме VERSION=xx.yy.zz, где xxи т. д. может быть любой строкой цифр, используйте

sed 's/\(VERSION=\)[[:digit:]]\{1,\}\.[[:digit:]]\{1,\}\.[[:digit:]]\{1,\}/\15.6.10/'

или, если вы хотите использовать [0-9]вместо[[:digit:]]:

sed 's/\(VERSION=\)[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}/\15.6.10/'

или, если вы хотите использовать расширенные, а не базовые регулярные выражения,

sed -E 's/(VERSION=)[0-9]+\.[0-9]+\.[0-9]+/\15.6.10/'

или, если вы хотите еще больше сжать,

sed -E 's/(VERSION=)([0-9]+\.){2}[0-9]+/\15.6.10/'

или, действительно,

sed 's/\(VERSION=\).*/\15.6.10/'

... если все, что вам нужно, это удалить все, что следует VERSION=из строки.

4
28.04.2021, 23:16

Теги

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