Reputation: 33
I have a line
echo "object smtp aaa smtp.asd.com server.smtp.com eq smtp"
object smtp aaa smtp.asd.com server.smtp.com eq smtp
and I need to replace the smtp with 25 but just were the smtp
is standing alone. The expected output should be
object 25 aaa smtp.asd.com server.smtp.com eq 25
It is not possible to use the \b or < > boundaries because there is a comma. I've tried to use
echo "object smtp aaa smtp.asd.com server.smtp.com eq 25" | sed -E 's/smtp[^.]?$/25/g'
object smtp aaa smtp.asd.com server.smtp.com eq 25
but it replaces just match at the end of the line. The
echo "object smtp aaa smtp.asd.com server.smtp.com eq smtp" | sed -E 's/smtp[^.]?( |$)/25/g'
object 25aaa smtp.asd.com server.smtp.com eq 25
replaces also the space. Does somebody has an idea how to solve the problem?
Upvotes: 0
Views: 64
Reputation: 627292
With a GNU sed, if you need to match smpt
as a whole word that has no dot at the end, you can use
s="object smtp aaa smtp.asd.com server.smtp.com eq smtp"
sed -E 's/\bsmtp([^.]|$)/25\1/g' <<< "$s"
See the online demo. Details:
\b
- a word boundarysmtp
- smtp
substring([^.]|$)
- Capturing group 1 (\1
refers to this value in the replacement): any char other than a .
char ([^.]
), or (|
) the end of string ($
).The same can be done with perl
:
s="object smtp aaa smtp.asd.com server.smtp.com eq smtp"
perl -pe 's/\bsmtp\b(?!\.)/25/g' <<< "$s"
See this online demo.
Here, \bsmtp\b(?!\.)
matches a whole word smtp
(with \bsmtp\b
) that is not immediately followed with a .
char ((?!\.)
).
Another solution with perl
is to match smtp
within whitespace boundaries:
perl -pe 's/(?<!\S)smtp(?!\S)/25/g' <<< "$s"
See this demo. However, in this case, it won't replace smtp
in smtp-server
since smtp
in this case should be inside whitespaces or start/end of string.
Upvotes: 0
Reputation: 785761
You may use this sed
:
s="object smtp aaa smtp.asd.com server.smtp.com eq smtp"
sed -E -e ':a' -e 's/(^|[[:blank:]])smtp([[:blank:]]|$)/\125\2/g;ta' <<< "$s"
object 25 aaa smtp.asd.com server.smtp.com eq 25
Here:
:a
: Sets label a
s/(^|[[:blank:]])smtp([[:blank:]]|$)/\125\2/g
replaces each smtp
with 25
if it preceded by start position or whitespace and if it is followed by whitespace or end positionta
: Goes back to label a
if substitution is successfulUpvotes: 1