sed wyszukiwanie i zamiana całego słowa

120

Jak wyszukiwać i zamieniać całe słowa za pomocą seda?

Robić

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

zastąpi również częściowe dopasowania, [oldtext]których nie chcę, aby robił.

ksuralta
źródło

Odpowiedzi:

164

\ b w wyrażeniach regularnych dopasuj granice słowa (tj. miejsce między pierwszym znakiem słowa a znakiem innym niż słowo):

$ echo "bar embarassment" | sed "s/\bbar\b/no bar/g"
no bar embarassment
Joakim Lundborg
źródło
9
nie posix | GNU sed OK
Oleg Mazko
@OlegMazko Przyszedłem też szukać akceptowalnej metody posix do użycia w vimie i to, co zadziałało, to s / \ <7 // g. Próbowałem usunąć 7 na początku słowa w moim kodzie. To łącze, konkretnie rozwiązanie JP, doprowadziło mnie do odpowiedzi: stackoverflow.com/questions/3864467/… (z jakiegoś powodu nie mogłem uzyskać Markdown, aby osadzić go tak jak twój).
jimh
Dziękuję, że oszalałem, próbując zastąpić słowo "i" tak \band\buratowałem dzień :)
MitchellK
144

W systemie Mac OS X żadna z tych składni wyrażeń regularnych nie działa wewnątrz seda w celu dopasowania całych słów

  • \bmyWord\b
  • \<myWord\>

Posłuchaj mnie teraz i uwierz później, ta brzydka składnia jest tym, czego potrzebujesz:

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

Tak więc, na przykład, aby zastąpić miętę z Minty tylko dla całych słów:

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

Źródło: strona podręcznika re_format

Larry Gerndt
źródło
19
Po prostu zainstaluj GNU sed(i każde inne narzędzie GNU) przez MacPorts lub Homebrew i upewnij się, że jest pierwsze w twoim PATH. Możliwe jest sprawienie, aby Mac był dość użyteczny.
Jim Stewart,
9
@JimStewart świetny sposób na złamanie zestawu narzędzi, które zakładają, że „na OS X rób tak, jak OS Xers”. To powiedziawszy, zdecydowanie mogę zasugerować brew install coreutils, które poprzedzają wszystkie narzędzia GNU.
ELLIOTTCABLE
16
brew install gnu-seddo użyciagsed
k107
brew coreutils jest niesamowity. czy są jakieś inne pakiety brew, które instalują całą masę wersji poleceń GNU, czy muszę instalować resztę indywidualnie?
ckot
2
Korzystanie Perl jest zawsze lepszym rozwiązaniem: perl -pe 's|\bone\b|two|g'. Działa stabilnie, gdy sed zawodzi tu i tam.
Pavel Vlasov
13

Użyj \bdo granic słów:

sed -i 's/\boldtext\b/newtext/g' <file>
Mitch Wheat
źródło
3
Uważaj na []: o,l-> [newtext],[newtext]. Oczywiście miałeś na myśli sed -i 's/\boldtext\b/newtext/g'
JJoao
7

W jednym z moich komputerów ograniczanie słowa „ \b” (bez cudzysłowów) nie działało. Rozwiązaniem było użycie „ \<” jako początku separatora i „ \>” jako końcowego separatora.

Aby wyjaśnić na przykładzie Joakima Lundberga :

$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment
Bieg
źródło
2

w poleceniu powłoki:

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

lub:

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

ale jeśli jesteś w vimie, możesz użyć tylko późniejszego:

:% s/\<old\>/new/g
arganzheng
źródło
-1
$ echo "bar embarassment"|awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1'
no bar embarassment
ghostdog74
źródło
OP wyraźnie stwierdza „używanie seda”
ndemou
To jest złączenie typu split-manipulate-join, a nie czysta zamiana; echo " bar embarassment " | awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1' | cat -Epowoduje to zwinięcie wielu spacji w jedną i odrzucenie wszelkich spacji wiodących / końcowych: np no bar embarassment$. daje .
musiphil