Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

There is an example in this link about sed:

To delete the first number on all lines that start with a "#" use:

sed '/^#/ s/[0-9][0-9]*//'

What is the benefit of first pattern(/^#/)? It could be simply:

sed 's/^#[0-9][0-9]*//'
share|improve this question
I don't get the [0-9][0-9]* why not [0-9]\+? – Bernhard Apr 18 '12 at 6:39
@Bernhard One good reason is maximum portability. I don't think \+ is guaranteed by POSIX. – jw013 Apr 18 '12 at 7:22
@Barnhard I just copied it from the link. But this wikipedia article says that \+ is in POSIX extended regular expressions. en.wikipedia.org/wiki/Regular_expression#Syntax – Majid Azimi Apr 18 '12 at 7:54
POSIX sed uses BRE's though. – jw013 Apr 18 '12 at 8:50
Every modern implementation of sed I've encountered has the ability to use EREs (sometimes with flag -r, other times with flag -E), and there is talk of adding this capacity to the POSIX standard for sed. @jw013 is correct though that the current POSIX standard doesn't require sed to handle anything other than BREs. EREs handle plain +; some sed implementations enhance their BREs to also handle \+, but if I remember rightly, this is not part of POSIX. Instead of p\+ you could use p\{1,\}, which is a POSIX BRE. – dubiousjim Oct 16 '12 at 15:51
up vote 6 down vote accepted

The general format of sed commands is

[address[,address]] function

When a command has a single address, it operates on all lines that match that address. When a command has no address, it operates on every single line.

Reference: POSIX sed

Regarding your specific examples:

  • /^#/ s/[0-9][0-9]*//

    • This command has an address, /^#/, which matches all lines beginning with a #.

    • The substitution pattern is /[0-9][0-9]*/. This matches the first sequence of digits wherever it occurs in the line.

    • Plain English summary: delete the first sequence of digits in every line beginning with a #.

    • Example: # non-digits|5555|non-digits|5555 becomes # non-digits||non-digits|5555

  • s/^#[0-9][0-9]*//

    • There is no address, so this command operates on every single line.

    • The substitution pattern, /^#[0-9][0-9]*/, matches a sequence of consecutive digits preceded by a # anchored at the beginning of the line.

    • Plain English summary: delete # followed by a sequence of digits (and only that pattern) from the beginning of every line.

    • Example: #5555|non-digits|5555 becomes |non-digits|5555, but # non-digits|5555|non-digits|5555 is unchanged because the substitution pattern does not match.

share|improve this answer

The first will match and substitute:


The second will not.

Plus, the second will also remove the initial #.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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