regexbashsedreplacedelimiter

sed regex, match first instance between varied delimeters


I have a set of hashes that I want to anonymize. Using GNU sed (v4.9), how can I replace only parts of the hash with something else? Specifically for my case, I want to preserve the $ symbol if it exists, but only if it is directly in front of the :.
(sed is not necessarily a requirement. Other commands that can do this, while accepting piped input, would work just as well. I just need this to work on the cli as part of a chain of piped commands. So not split over multiple lines is preferred)

Example:

USER:1234:aad3b435b:abcdef:::
COMPUTER$:4321:aad3b435b:abcdef:::
DOMAIN\bleh:5678:eaad3b4:fedcba:::
DOMAIN\$why:5678:eaad3b4:fedcba:::

Using the following command I am almost able to get what I want

sed 's/[^$:]\+/REDACTED/1'
REDACTED:1234:aad3b435b:abcdef:::
REDACTED$:4321:aad3b435b:abcdef:::
REDACTED:5678:eaad3b4:fedcba:::
REDACTED$why:5678:eaad3b4:fedcba:::

However, as can be seen, this sed regex matches the last entry wrong. It should instead be

REDACTED:5678:eaad3b4:fedcba:::

The sed command should replace anything between the start of line ^ and $: OR :.

I don't know what I'm doing wrong. I have tried and tried to get the "or" clause to work properly using grouping and lookahead/behind and escaping characters but I can't get the result I want. From what I understand sed uses basic regex by default, but I can't seem to find the solution using -E or -r either...


Solution

  • This works for me:

    $ sed 's/^[^:]*[^:$]/REDACTED/' file
    REDACTED:1234:aad3b435b:abcdef:::
    REDACTED$:4321:aad3b435b:abcdef:::
    REDACTED:5678:eaad3b4:fedcba:::
    REDACTED:5678:eaad3b4:fedcba:::