sed busca e substituição de palavra inteira

120

Como faço para pesquisar e substituir palavras inteiras usando sed?

Fazendo

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

também substituirá correspondências parciais das [oldtext]quais não quero fazer.

ksuralta
fonte

Respostas:

164

\ b em expressões regulares correspondem aos limites da palavra (ou seja, a localização entre o caractere da primeira palavra e o caractere não verbal):

$ echo "bar embarassment" | sed "s/\bbar\b/no bar/g"
no bar embarassment
Joakim Lundborg
fonte
9
não posix | GNU sed OK
Oleg Mazko
@OlegMazko Eu também vim procurando o método posix aceitável para usar no vim e o que funcionou para mim foi s / \ <7 // g. Eu estava tentando remover um 7 no início de uma palavra em meu código. Este link, especificamente a solução do JP, me levou à resposta: stackoverflow.com/questions/3864467/… (não foi possível obter o markdown para incorporá-lo como o seu por algum motivo).
Jimh
Obrigado. Eu estava ficando louco tentando fazer uma substituição na palavra "e" então \band\bsalvei o dia :)
MitchellK
144

No Mac OS X, nenhuma dessas sintaxes regex funciona dentro do sed para combinar palavras inteiras

  • \bmyWord\b
  • \<myWord\>

Ouça-me agora e acredite em mim mais tarde, esta sintaxe feia é o que você precisa usar:

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

Assim, por exemplo, para substituir hortelã por mentolado apenas para palavras inteiras:

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

Fonte: página do manual re_format

Larry Gerndt
fonte
19
Basta instalar o GNU sed(e todas as outras ferramentas GNU) através do MacPorts ou Homebrew e certifique-se de que ele vem primeiro no seu PATH. É possível tornar um Mac razoavelmente utilizável.
Jim Stewart de
9
@JimStewart é uma ótima maneira de quebrar um monte de ferramentas que assumem 'quando no OS X, faça como os OS Xers.' Dito isso, posso definitivamente sugerir brew install coreutils, que prefixa todas as ferramentas gnu.
ELLIOTTCABLE
16
brew install gnu-sedpara usargsed
k107
brew coreutils é incrível. Existem outros pacotes de cerveja que instalam um monte de versões GNU de comandos ou eu preciso instalar o resto individualmente?
ckot
2
Usando perl é sempre uma solução melhor: perl -pe 's|\bone\b|two|g'. Funciona de forma estável enquanto o sed falha aqui e ali.
Pavel Vlasov,
13

Use \bpara limites de palavras:

sed -i 's/\boldtext\b/newtext/g' <file>
Trigo mitch
fonte
3
Cuidado com []: o,l-> [newtext],[newtext]. Você obviamente quis dizer sed -i 's/\boldtext\b/newtext/g'
JJoao
7

Em uma das minhas máquinas, delimitar a palavra com " \b" (sem as aspas) não funcionou. A solução foi usar " \<" para iniciar o delimitador e "\> " para delimitador final.

Para explicar com o exemplo de Joakim Lundberg :

$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment
Uma corrida
fonte
2

no comando shell:

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

ou:

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

mas se você estiver no vim, você só pode usar o mais tarde:

:% s/\<old\>/new/g
Arganzheng
fonte
-1
$ echo "bar embarassment"|awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1'
no bar embarassment
ghostdog74
fonte
OP declara explicitamente "usando sed"
ndemou
Esta é uma junção de manipulação de divisão, não uma substituição pura; isso reduz vários espaços em um e descarta todos os espaços iniciais / finais: por exemplo, echo " bar embarassment " | awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1' | cat -Eno bar embarassment$.
musiphil