#bash #shell
Вопрос:
Я пытаюсь заменить слово в строке, содержащей то же слово, специальным символом в нем.
Пример:
string="this is a joke. this is a poor-joke. this is a joke-club"
Я просто хочу заменить слово «шутка» на «кока-кола», а не на специальный символ.
приведенная ниже команда заменяет все слово шутка.
[chandu@mynode ~]$ echo $string | sed "s/joke/coke/g;"
this is a coke. this is a poor-coke. this is a coke-club
Я пробовал использовать sed "s/<joke>/coke/g;"
но даже это заменяет все слова
Ожидаемый результат: this is a coke. this is a poor-joke. this is a joke-club
Комментарии:
1. Зачем вы используете
/g
флаг, если это не то, чего вы хотите?2. Я не совсем понимаю, что вы имеете в виду под особым характером. Не могли бы вы привести нам пример, который работает не так, как ожидалось?
3. разве точка
.
не является особым символом?4. приведенная выше строка является примером. Мой фактический файл огромен и содержит слово «шутка» несколько раз. Это причина, по которой я пользуюсь
/g
.
Ответ №1:
Вы можете сами сопоставить начало и окончание слова, если хотите включить -
его в качестве символа слова.
$ sed 's/(^|[^a-zA-Z-])joke([^a-zA-Z-]|$)/1coke2/g' <<<"$string"
this is a coke. this is a poor-joke. this is a joke-club
Ответ №2:
Использование perl и look-around для определения благоприятных начальных (пробел) и конечных (пробел или точка) символов вокруг слова joke
:
$ echo $string | perl -p -e 's/(?<=[ ])joke(?=[. ])/coke/g'
Выход.
this is a coke. this is a poor-joke. this is a joke-club
Комментарии:
1. Как насчет этой строки :
this is a joke. this is a poor-joke. this is a joke
?2. @Philippe Каковы ожидаемые результаты? Если вы ссылаетесь на слово
joke
в конце строки, измените группу символов для положительного прогноза на[. n]
.3. … или к
(?=([. ]|$))
. Так, наверное, лучше.4. Да, я имел в виду слово «шутка» в конце строки, Разумно, ОП ожидает, что его заменят.
Ответ №3:
К сожалению, в вашем случае дефис разделяет строку на разные слова.
т. е.: если я изменю вашу строку на:
string='this is a joke. this is a poorjoke. this is a jokeclub'
и я выполняю команду:
echo $string | sed 's/bjokeb/coke/g'
(где b означает: граница слова), я получаю следующий результат:
this is a coke. this is a poorjoke. this is a jokeclub
Но когда я применяю ту же команду к вашей строке, я получаю (как и вы):
this is a coke. this is a poor-coke. this is a coke-club
Итак, в вашем конкретном случае я бы попробовал что-то вроде:
echo $string | sed 's/([^-])(joke)([^-])/1coke3/g'
Что приводит к следующему результату:
this is a coke. this is a poor-joke. this is a joke-club