0

I'm trying to replace bobearl with jim in the following string

"billy" "bobearl" and "johnny"

I can do something like this:

sed 's/bob/jim/' /tmp/text.txt
"billy" "jimearl" and "johnny"

but that leaves earl

I can do this:

sed 's/bob.*/jim/' /tmp/text.txt
"billy" "jim

But that removes everything after the replacement string.

What is the most efficient way to replace bobearl with jim while not changing anything else? I assume my issues has something to do with the quotes but I'm just not sure how to get it to work.

8
  • 4
    The obvious answer is to use the whole string bobearl to match with in the substitution. Do you have any restrictions that you haven't told us about that prevents you from doing that?
    – Kusalananda
    Commented Mar 13 at 20:58
  • Or maybe use sed 's/"bob[^"]*"/"jim"/' to make sure it only replaces double-quoted strings that start with bob
    – Fravadona
    Commented Mar 14 at 8:01
  • Yes, the bobearl string was just an example. The real string is rather long and contains multiple blocks of text separated by quotes. This is the actual string: <ssl enabled="true" wallet-file="/u01/<redacted>/wallet" ssl-versions="TLSv1.0, TLSV1.1,TLSv1.2" ssl-ciphers="SSL_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_AES_128_GCM_SHA256"/> I need to replace ssl-versions="TLSv1.0, TLSV1.1,TLSv1.2" to it contains just TLSv1.2. The problem is ssl-versions= could contain any number of values so I can't match on an exact string.
    – goswell
    Commented Mar 14 at 15:52
  • In english, what I want to do is find the phrase ssl-versions= and replace whatever is between the next two quotes with "TLSv1.2" but do not change anything else.
    – goswell
    Commented Mar 14 at 16:04
  • This suggestion seems to work and doesn't over complicate it. sed 's/"bob[^"]*"/"jim"/' I modified it to this for my actual need: sed 's/ssl-versions="[^"]*"/ssl-versions="TLSv1.2"/'
    – goswell
    Commented Mar 14 at 17:27

1 Answer 1

4

Since bob does not match bobearl your expression s/bob/jim/ will not replace bobearl, it will only replace the bob.

If you match bobearl it will replace bobearl:

$ echo '"billy" "bobearl" and "johnny"' | sed 's/bobearl/jim/'
"billy" "jim" and "johnny"

If you are looking to use a wildcard match without globbing the rest of the line you can do something like this:

 sed -E 's/\bbob\w*?\b/jim/'
  • -E use extended regex
  • \b matches word boundaries
  • \w*? match zero or more word characters non greedy
2
  • 1
    I know at least GNU sed supports the Perl-like \w in extended regex mode - but does it really understand *? as a non-greedy quantifier (or is it just matching zero or more word characters, zero or one times here)? A more portable alternative might be to simply match zero or more non-quotes, bob[^"]*. Commented Mar 13 at 22:02
  • @steeldriver No, sed does not understand *?, despite what POSIX now claims EREs should support.
    – Ed Morton
    Commented Mar 16 at 14:53

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.