sed поиск целого слова и замена

120

Как искать и заменять целые слова с помощью sed?

дела

sed -i 's/[oldtext]/[newtext]/g' <file> 

также заменит частичные совпадения, [oldtext]которых я не хочу.

ksuralta
источник

Ответы:

164

\ b в регулярных выражениях соответствует границам слова (то есть местоположению между первым символом слова и символом, не являющимся словом):

$ echo "bar embarassment" | sed "s/\bbar\b/no bar/g"
no bar embarassment
Йоаким Лундборг
источник
9
не posix | GNU sed OK
Олег Мазко
@OlegMazko Я также искал приемлемый метод posix для использования в vim, и у меня сработало s / \ <7 // g. Я пытался удалить 7 в начале слова в моем коде. Эта ссылка, в частности решение JP, привела меня к ответу: stackoverflow.com/questions/3864467/… (по какой-то причине не удалось получить уценку, чтобы встроить его, как ваше).
Джим
Спасибо, я сошел с ума, пытаясь сделать замену на слово «и», так что \band\bспас положение :)
MitchellK
145

В Mac OS X ни один из этих синтаксисов регулярных выражений не работает внутри sed для сопоставления целых слов.

  • \bmyWord\b
  • \<myWord\>

Услышьте меня сейчас и поверьте мне позже, этот уродливый синтаксис - это то, что вам нужно использовать:

  • /[[:<:]]myWord[[:>:]]/

Так, например, заменить мяту с Минти для только целых слов:

  • sed "s/[[:<:]]mint[[:>:]]/minty/g"

Источник: справочная страница re_format

Ларри Герндт
источник
19
Просто установите GNU sed(и любой другой инструмент GNU) через MacPorts или Homebrew и убедитесь, что он идет первым в вашем PATH. Можно сделать Mac достаточно удобным в использовании.
Джим Стюарт,
9
@JimStewart - отличный способ сломать кучу инструментов, которые предполагают, что «в OS X действуйте как OS Xers». Тем не менее, я могу определенно предложить brew install coreutils, который является префиксом всех инструментов GNU.
ELLIOTTCABLE
16
brew install gnu-sedиспользоватьgsed
k107
brew coreutils - это круто. есть ли какие-либо другие пакеты brew, которые устанавливают целую кучу версий команд gnu, или мне нужно устанавливать остальные по отдельности?
ckot
2
Использование Perl всегда является лучшим решением perl -pe 's|\bone\b|two|g'. Работает стабильно, пока sed не работает то тут, то там.
Павел Власов
13

Используйте \bдля границ слов:

sed -i 's/\boldtext\b/newtext/g' <file>
Митч Уит
источник
3
Будьте осторожны с []: o,l-> [newtext],[newtext]. Вы, очевидно, имели в виду sed -i 's/\boldtext\b/newtext/g'
JJoao
7

На одной из моих машин разделение слова " \b" (без кавычек) не работало. Решением было использовать « \<» для начального разделителя и « \>» для конечного разделителя.

Чтобы объяснить на примере Йоакима Лундберга :

$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment
Arun
источник
2

в команде оболочки:

echo "bar embarassment" | sed "s/\bbar\b/no bar/g" 

или:

echo "bar embarassment" | sed "s/\<bar\>/no bar/g"

но если вы находитесь в vim, вы можете использовать только последнее:

:% s/\<old\>/new/g
arganzheng
источник
-1
$ echo "bar embarassment"|awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1'
no bar embarassment
ghostdog74
источник
OP явно заявляет «с использованием sed»
ndemou
Это разделение-манипуляция-соединение, а не чистая замена; это сворачивает несколько пробелов в один и отбрасывает любые начальные / конечные пробелы: например, echo " bar embarassment " | awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1' | cat -Eдает no bar embarassment$.
musiphil