sed ricerca e sostituzione di parole intere


120

Come cerco e sostituisco parole intere usando sed?

fare

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

sostituirà anche le corrispondenze parziali di [oldtext]cui non voglio che faccia.

Risposte:


164

\ b nelle espressioni regolari corrisponde ai confini delle parole (cioè la posizione tra il primo carattere della parola e il carattere non della parola):

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


@OlegMazko Sono anche venuto alla ricerca del metodo accettabile posix da usare in vim e quello che ha funzionato per me è stato s / \ <7 // g. Stavo cercando di rimuovere un 7 all'inizio di una parola nel mio codice. Questo link, in particolare, la soluzione di JP, mi ha portato alla risposta: stackoverflow.com/questions/3864467/… (non è stato possibile ottenere il markdown per incorporarlo come il tuo per qualche motivo).
jimh

Grazie stavo impazzendo cercando di sostituire la parola "e" così ho \band\bsalvato la giornata :)
MitchellK

144

Su Mac OS X, nessuna di queste sintassi regex funziona all'interno di sed per la corrispondenza di parole intere

  • \bmyWord\b
  • \<myWord\>

Ascoltami ora e credimi più tardi, questa brutta sintassi è ciò che devi usare:

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

Quindi, ad esempio, per sostituire la menta con menta solo per parole intere:

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

Fonte: pagina man di re_format


19
Installa GNU sed(e ogni altro strumento GNU) tramite MacPorts o Homebrew e assicurati che venga prima nel tuo file PATH. È possibile rendere un Mac abbastanza utilizzabile.
Jim Stewart

9
@JimStewart è un ottimo modo per rompere un mucchio di strumenti che presumono "quando su OS X, fai come OS Xers." Detto questo, posso sicuramente suggerire brew install coreutils, che fa da prefisso a tutti gli strumenti gnu.
ELLIOTTCABLE

16
brew install gnu-sedda usaregsed
k107

brew coreutils è fantastico. ci sono altri pacchetti brew che installano un sacco di versioni di comandi GNU o devo installare il resto individualmente?
ckot

2
Utilizzando perl è sempre una soluzione migliore: perl -pe 's|\bone\b|two|g'. Funziona stabilmente mentre sed fallisce qua e là.
Pavel Vlasov

13

Utilizzare \bper i confini delle parole:

sed -i 's/\boldtext\b/newtext/g' <file>

3
Stai attento con []: o,l-> [newtext],[newtext]. Ovviamente intendevi sed -i 's/\boldtext\b/newtext/g'
JJoao

7

In una delle mie macchine, delimitare la parola con " \b" (senza virgolette) non ha funzionato. La soluzione era usare " \<" per il delimitatore iniziale e " \>" per il delimitatore finale.

Per spiegare con l'esempio di Joakim Lundberg :

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

2

nel comando della shell:

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

o:

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

ma se sei in vim, puoi usare solo il successivo:

:% s/\<old\>/new/g

-1
$ echo "bar embarassment"|awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1'
no bar embarassment

OP afferma esplicitamente "using sed"
ndemou

Questo è uno split-manipulate-join, non una pura sostituzione; questo comprime più spazi in uno e scarta tutti gli spazi iniziali / finali: es . echo " bar embarassment " | awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1' | cat -Eno bar embarassment$.
musiphil
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.