I know there are lots of questions about it but I can't get it working.

I want to clean a group (for instance root) in /etc/group with sed or awk. So I need to delete everything after root:*:0:

I tried to remove it with:

cat /etc/group | awk '!p;/^root:*:0:/{p=1}'


cat /etc/group | sed 's/root\:\*\:0\:.*//'

but sed removes the whole root line.

What am i doing wrong?

  • 1
    When you say everything after do you mean a) everything after that string on the line containing it, or b) every line in the file after the line containing that string, or c) everything after that string on the line containing that string plus every line after it, or d) something else? Is the * in your example supposed to be literal or the regexp repetition metachar? Please edit your question to show concise, testable sample input and expected output to help clarify your requirements and give us something we can test a potential solution against. – Ed Morton Feb 20 '20 at 14:57

You can use an address with sed to limit what lines to act on:

 sed '/^root:/s/:[^:]*$/:/' /etc/group

Which, for the line(s) starting with root:, removes all characters after the last : in the line.

(/etc/group records only have 4 :-delimited columns, so it strips the last one with all the group members in it)

  • 1
    That would modify lines starting with root:foo:bar, not just lines starting with root:*:0: as the OP says they want. – Ed Morton Feb 20 '20 at 15:04
  • 1
    @EdMorton /etc/group is extremely unlikely to have more than one root group, and it's not going to look notably different (Mine is root:x:0:; I wonder what OS uses an asterisk for the password field). – Shawn Feb 20 '20 at 15:06
  • I wasn't imagine them having more than one root group, rather that they only want to modify the one they have if it looks like they specified. – Ed Morton Feb 20 '20 at 15:14

With awk:

awk 'BEGIN{OFS=FS=":"} $1=="root"{$NF=""} 1' /etc/group

Split fields on : and set the last field to an empty string if the first field is root.


Apart from the question whether this should really be done using simple text-processing tools, your sed call clears the entire line because the "substitute" command replaces the entire found pattern with the replacement (in your case the empty string).

The minimal modification to get your sed line to work would be to write

sed 's/root:\*:0:.*/root:*:0:/' /etc/group

or, using capture groups,

sed 's/\(root:\*:0:\).*/\1/' /etc/group

(and btw, cat is never necessary when using sed or awk, just provide the file as command-line argument).

The solution presented by @Shawn is however more elegant in that respect.


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.