It sounds like it should be trivial task, but I cannot figure it out, so I decided to ask. I need to replace the whole line, but optional last character. For instance, I want:
abcd to become efgh but
abcd, to become efgh,
How can I create regex like that? It seems optional character cannot be back-referenced, i.e something like: s/.*\(,\)?$/efgh\1 won't work (I tried :) ) To make it clear, the lines are arbitrary length with arbitrary characters. The only condition in my case is to preserve comma at the end of the line after the replacement if one existed there or drop it if line did not end up with comma

  • 1
    Any length lines? Always abcd? Always a comma? How do we tell whether or not the last character should be kept? – roaima Apr 8 at 20:37
  • What tool are you using to apply the RE? Different tools use different variants (unfortunately). – roaima Apr 8 at 20:41
  • .* is greedy, meaning it will match the whole string first then try the rest of the match, which since the next group is optional it will never get matched. Some regex flavors have a reluctant quantifier which will try matching the least amount of characters. – Torin Apr 8 at 20:46

Another one:

$ echo -e "abcd\nabcd," | sed 's/.*\($\|,\)/efgh\1/'

This matches the end of the line $ or the comma , in the captured group.

  • Thank you so much! That's exactly what I was looking for. I totally forgot that capturing group may have more than 1 character! I hope this solution will save time for somebody else in the future as well. – Shimon Pozin Apr 9 at 1:08

I believe you are referring to something like:


Complete sed commands + output:

$ echo "abcd," | sed 's/[a-z]\+\([^a-z]\{0,1\}\)$/efgh\1/g'

$ echo "abcd" | sed 's/[a-z]\+\([^a-z]\{0,1\}\)$/efgh\1/g'
  • I think this works for specific example I gave, but I am not sure about arbitrary line (i search for specific pattern in the line, but then replace it entirely, preserving only comma at the end of the line) So, if I read it correct, we capture end of line that is not a letter and appears 0 or 1 times, right? But if it's a period, it will preserve it too? I only need to preserve it if it's comma. If it's ending of json statement, for example ("xxx}") I don't want to preserve the last character. But if it's "xxx}," then I do want to transfer comma into replacement. Sorry if I was not clear. – Shimon Pozin Apr 9 at 1:17
  • @ShimonPozin You are correct in your comment here. You could change [^a-z] to just , in the given regular expression (and delete the g at the end as the substitution would by necessity only match once ever). – Kusalananda Apr 9 at 6:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.