1
votes

I've looked around some other peripheral questions and haven't been able to find a solution to my problem, so I'm sorry if this is a duplicate to something I missed.

Basically, I have the following GNU sed command:

sed -E -imr 's/^(\w)+/(\w)+$/g' file

which is supposed to replace the first word of a line with the last word of the line.

The first regex ^(\w)+ works great and matches the first word of each line. The problem is that the command replaces that first word with the literal string (w)+$

I've tried to escape the backslash, the parentheses, the operators, but I've had no luck in making the regex work in the output part of the command.

Can one use a regex capture group to replace a different regex capture group? What needs to be escaped, or what alternative syntax needs to be used?

NOTE

I'm using GNU sed on macOS from brew installed coreutils, so the answers to this question might not work across other versions of sed like native BSD on macOS.

1
Try sed -E -imr 's/^(\w+)(.*\W)(\w+)$/\3\2\1/g' file (if \w and \W work at all, maybe [[:alnum:]] and [^[:alnum:]] will be better).Wiktor Stribiżew
In the replacement field you can't use regex syntax, but you are supposed to use plain text and some special symbols (e.g. \1 returns the first capturing group).horcrux
@CasimiretHippolyte I think it's because he's using GNU sed on macos. The native sed command has no such option. There is, of course, a solution that will work with BSD sed but he's not using that version.Jeff Holt
@ezra I upvoted your question taking it from -2 to -1. I think one of the reasons it got voted down might be the nouns you used in the title. If I had written the title it would have read "Replace one capture group with another using GNU sed", possibly even including the version of sed.Jeff Holt
@jeff6times7 Thanks for the vote, that makes sense. I feel like part of the issue of not being able to find the answer online is not having the vocabulary to search for the right answer. It's interesting that some people downvote over that but I also get why a misused phrase in a title can be annoying. Thanks for the heads up. edit -- also I changed the title to reflect your suggestion.Ezra Goss

1 Answers

5
votes

The replacement doesn't contain a regex, it contains a string which could reference capture groups defined in the regex. To replace the first word by the last one, you need to capture the last word and the rest of the line:

sed -r 's/^\w+(.*\b)(\w+)$/\2\1/'  
            |    |    |
         Matches |    |
         the 1st |    Matches the last word
         word    |
                Matches everything in the middle
                up to a "word boundary"

Note that -r, \w, and \b might not work in all sed versions, but they should work in recent GNU sed.