sed recherche et remplacement de mot entier

120

Comment rechercher et remplacer des mots entiers en utilisant sed?

Faire

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

remplacera également les correspondances partielles [oldtext]dont je ne veux pas qu'il le fasse.

ksuralta
la source

Réponses:

164

\ b dans les expressions régulières correspond aux limites des mots (c'est-à-dire l'emplacement entre le premier caractère de mot et le caractère non-mot):

$ echo "bar embarassment" | sed "s/\bbar\b/no bar/g"
no bar embarassment
Joakim Lundborg
la source
9
pas posix | GNU sed OK
Oleg Mazko
@OlegMazko Je suis également venu à la recherche de la méthode posix acceptable à utiliser dans vim et ce qui a fonctionné pour moi était s / \ <7 // g. J'essayais de supprimer un 7 au début d'un mot dans mon code. Ce lien, en particulier la solution de JP, m'a conduit à la réponse: stackoverflow.com/questions/3864467/… (impossible d'obtenir une démarque pour l'intégrer comme la vôtre pour une raison quelconque).
jimh
Merci, je devenais fou en essayant de faire un remplacement sur le mot "et" donc \band\bsauvé la journée :)
MitchellK
145

Sur Mac OS X, aucune de ces syntaxes regex ne fonctionne dans sed pour faire correspondre des mots entiers

  • \bmyWord\b
  • \<myWord\>

Écoutez-moi maintenant et croyez-moi plus tard, cette vilaine syntaxe est ce que vous devez utiliser:

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

Ainsi, par exemple, pour remplacer menthe par menthe pour les mots entiers uniquement:

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

Source: page de manuel re_format

Larry Gerndt
la source
19
Installez simplement GNU sed(et tous les autres outils GNU) via MacPorts ou Homebrew et assurez-vous qu'il vient en premier dans votre PATH. Il est possible de rendre un Mac assez utilisable.
Jim Stewart
9
@JimStewart est un excellent moyen de briser un tas d'outils qui supposent que `` sous OS X, faites comme les OS Xers ''. Cela dit, je peux certainement suggérer brew install coreutils, qui préfixe tous les outils gnu.
ELLIOTTCABLE
16
brew install gnu-sedà utilisergsed
k107
brasser coreutils est génial. y a-t-il d'autres packages de brassage qui installent tout un tas de versions gnu de commandes ou dois-je installer le reste individuellement?
ckot
2
L' utilisation de Perl est toujours une meilleure solution: perl -pe 's|\bone\b|two|g'. Fonctionne de manière stable tandis que sed échoue ici et là.
Pavel Vlasov
13

Utiliser \bpour les limites de mots:

sed -i 's/\boldtext\b/newtext/g' <file>
Blé Mitch
la source
3
Soyez prudent avec []: o,l-> [newtext],[newtext]. Vous sed -i 's/\boldtext\b/newtext/g'
vouliez
7

Dans l'une de mes machines, délimiter le mot par " \b" (sans les guillemets) ne fonctionnait pas. La solution consistait à utiliser " \<" pour commencer le délimiteur et "\> " pour le délimiteur de fin.

Pour expliquer avec l'exemple de Joakim Lundberg :

$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment
Arun
la source
2

dans la commande shell:

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

ou:

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

mais si vous êtes dans vim, vous ne pouvez utiliser que le plus tard:

:% s/\<old\>/new/g
arganzheng
la source
-1
$ echo "bar embarassment"|awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1'
no bar embarassment
ghostdog74
la source
OP déclare explicitement "using sed"
ndemou
Il s'agit d'une jointure de manipulation fractionnée, pas d'un remplacement pur; cela réduit plusieurs espaces en un seul et supprime tous les espaces de début / de fin: par exemple, echo " bar embarassment " | awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1' | cat -Edonne no bar embarassment$.
musiphil