I am trying to find out what the following command means:

sed 's/-\([0-9.]\+\)/(\1)/g' inputfile

I know it has to do with non-digit characters.

closed as off-topic by RalfFriedl, Thomas Dickey, mdpc, Romeo Ninov, Toby Speight Sep 26 at 10:30

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Requests for learning materials (tutorials, how-tos etc.) are off topic. The only exception is questions about where to find official documentation (e.g. POSIX specifications). See the Help Center and our Community Meta for more information." – RalfFriedl, Thomas Dickey, mdpc, Romeo Ninov, Toby Speight
If this question can be reworded to fit the rules in the help center, please edit the question.

In GNU sed, it looks for a dash followed by some digits or dots, and replaces that with the same digits in parenthesis. That is, it turns -123.45 into (123.45).

In some other seds, like the BSD-based one on macOS, it looks for a dash, a digit or dot, and a literal plus sign, and then removes the dash and surrounds the rest in parenthesis. That is, it turns -1+ into (1+), but leaves stuff like -123 as-is.


The difference is because \+ does not have a standard meaning in basic regular expressions. GNU interprets it as the same as + in extended regexes, i.e. "one or more of the previous", while others take it as literal +.

As for the other parts in the left-hand pattern, the dash matches itself, [0-9.] matches any one digit or dot, and the \( .. \) capture the part in between. In the replacement, the parenthesis are literal, and \1 puts back whatever was within the \( .. \).

More portably, that should be either

  • in extended RE, assuming your sed supports -E, which many do:

    sed -E 's/-([0-9.]+)/(\1)/' 
    
  • in basic RE:

    sed 's/-\([0-9.]\{1,\}\)/(\1)/' 
    

Both should replace a dash in front of a number with parenthesis around it.

  • Thanks. The \+ meant to me to escape the plus sign, not the 1 or more meaning. – Arluin Sep 25 at 20:52
  • Note that while sed -E is probably going to be specified in the next major version of the POSIX standard, it's still not, and it's still not supported on many commercial Unices. There are also still systems out there with older versions of GNU or busybox sed supporting sed -r for that but not -E yet. So it's a bit early to say it's portable. – Stéphane Chazelas Sep 25 at 22:15
  • @StéphaneChazelas, ah right, sorry. fixed that first one. IIRC GNU sed supports -E as an undocumented feature since a long time. I have some GNU sed dated 2009, where -E works. That seems like a reasonable time to say it's probably ok by now (on GNU). – ilkkachu Sep 25 at 22:22

Looks like it changing the format of negative numbers from having a - in front of them to instead being surrounded by parentheses.

It searches for a sequence that starts with - followed by a sequence of numerals and decimals [0-9.] being a match to numerals and decimals, and \+ modifying it to match one or more such character in a sequence. The sequence of numerals and decimals are inside \(...\), which is the first expression, and in the replacement clause, (\1) will paste the first expression between (). End result is removal of a negative sign in front of a number and wrapping it in parentheses.

So with an input of:

test value: -123.4

the output should be of the form

test value: (123.4)
  • 2
    ...and adds parentheses around the result, too. Just changing the display style. – drewbenn Sep 25 at 18:56
  • 1
    Ah, yes, I did miss that. I'll edit it in. – Christian Gibbons Sep 25 at 18:57

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