Aqui, eu usaria perl
.
WORD=$word REPLACE=$replace perl -pi -e '
s/\b\Q$ENV{WORD}\E\b/$ENV{REPLACE}/g' file
sed
(mesmo GNU sed
) não tem equivalente para \Q\E
, que você precisa aqui para que o $word
não seja considerado como um regexp. E a maioria das implementações sed
não suportam -i
(ou suportam com sintaxe diferente) ou \b
.
\b
corresponde a uma transição entre um caractere e não-palavra .
Portanto, \b\Q1.1.2.3\E\b
ainda corresponderia a 1.1.2.3.4
, pois .
é uma não palavra .
Você também pode fazer:
WORD=$word REPLACE=$replace perl -pi -e '
s/(?<!\S)\Q$ENV{WORD}\E(?!\S)/$ENV{REPLACE}/g' file
Para corresponder em $word
desde que não seja precedido nem seguido por um caractere sem espaçamento. (usando (?<!)
e (?!)
negativo para trás / para frente).
Observe que perl
por padrão funcionará com caracteres ASCII. Por exemplo, um caractere palavra seria apenas _a-zA-Z0-9
( \b\Q1.2.3\E\b
corresponderia em 1.2.3é
e \S
corresponderia a bytes individuais de caracteres de espaçamento unicode estendidos). Para dados não ASCII, você provavelmente desejará adicionar a opção -CLSD
a perl
.
Alguns exemplos:
$ export WORD=1.1.1.3 REPLACE=REPLACE
$ printf '1.1.1.3-x 1.1.1.3\u2006 1.1.1.3.4 1.1.123 1.1.1.3\u20dd 1.1.1.3\ue9\n' > f
$ cat f
1.1.1.3-x 1.1.1.3 1.1.1.3.4 1.1.123 1.1.1.3⃝ 1.1.1.3é
$ perl -pe 's/\b\Q$ENV{WORD}\E\b/$ENV{REPLACE}/g' f
REPLACE-x REPLACE REPLACE.4 1.1.123 REPLACE⃝ REPLACEé
$ perl -CLSD -pe 's/\b\Q$ENV{WORD}\E\b/$ENV{REPLACE}/g' f
REPLACE-x REPLACE REPLACE.4 1.1.123 1.1.1.3⃝ 1.1.1.3é
$ perl -pe 's/(?<!\S)\Q$ENV{WORD}\E(?!\S)/$ENV{REPLACE}/g' f
1.1.1.3-x 1.1.1.3 1.1.1.3.4 1.1.123 1.1.1.3⃝ 1.1.1.3é
$ perl -CLSD -pe 's/(?<!\S)\Q$ENV{WORD}\E(?!\S)/$ENV{REPLACE}/g' f
1.1.1.3-x REPLACE 1.1.1.3.4 1.1.123 1.1.1.3⃝ 1.1.1.3é
$ sed "s/\b$WORD\b/$REPLACE/g" f
REPLACE-x REPLACE REPLACE.4 REPLACE REPLACE⃝ 1.1.1.3é