0

I'm trying to pull out the third subexpression from this line:

#EXTRA_GROUPS="dialout cdrom floppy audio video plugdev users"

(yep, the adduser.conf file, for those of you who are curious) with:

sed 's/\(EXTRA_GROUPS=\)\("\)\(.*\)\("\)/\3/' adduser.conf

While this does work and produces

#dialout cdrom floppy audio video plugdev users

(I've left the # symbol out of the expression, so please disregard), this

sed 's/\(EXTRA_GROUPS=\)\("\)\(.*\)\("\)//3' adduser.conf

doesn't and leaves the file as is.

I do realize that the last example is supposed to delete back reference number three, but when I modify the command with /sd/3 ("replace 3rd subexpression with sd") it doesn't really do anything, either.

I have tried running the command with the -n //p options-all to the same result.

I'm using GNU sed version 4.2.2 on a Debian Jessie box.

Have I missed some crucial part of my core utilities "education" or is it that I haven't been out in the sun for while?

  • 2
    s/.../.../3 means "replace 3rd occurrence" (of the entire pattern), not "replace 3rd subexpression". – Satō Katsura Apr 4 '17 at 11:10
4

The /n flag to the substitute command s in sed does not have anything to do with the back-reference \n.

  • With, e.g., s/regex/string/3 you replace the third match of regex (on the current line) with string.
  • With s/regex/\3/, you replace the first match of regex with the third capture-group.
  • With s/regex/\3/3, you replace the third match of regex with the third capture-group.

In this case, I would probably go with something simpler, like

sed 's/^.*EXTRA_GROUPS="\([^"]*\)".*$/\1/'

There's no use in capturing bits of the string if you're not using it.

  • To clarify, I was referring to the sed -n 's///p' filename(print only the modified line) command. But in any case-killer! That answers my question! I was also curious if I can replace the third regex with some new string, in this case everything inside the double quotes "dialout, cdrom, floppy..." with, say "foobar"? – Max Apr 4 '17 at 11:22
  • @Kusalananda: Since you have .* at the beginning and at the end of the pattern, you can leave out the ^ and $, because greedy * will eat up everything to the bounds of the line anyhow. As well, you can replace [^"] with ., as long as behaviour for additional double quotes is undefined. – Philippos Apr 4 '17 at 11:40

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.