2

Using 'sed' I want to replace any 10 digit sequence with 1234567890

This works but is not very elegant

echo "code=1111111111" | sed 's/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/1234567890/'

This does not work

echo "code=1111111111" | sed 's/[0-9]{10}/1234567890/'

result

code=1111111111

Can anyone suggest an simple elegant solution that uses 'sed' ?

4
  • Would you also want to change the sequence of 2's in beep2222222222111=0000000000? Another way to ask the same thing: Should only the part after the = be considered, and should it only change if it's 10 digits (not more and not fewer)?
    – Kusalananda
    May 11, 2023 at 11:23
  • Thanks. I meant only the digits after the equals sign. And in my case the input would typically only contain a 10 digit number. May 12, 2023 at 7:27
  • So the issue is not actually about matching ten digits, but to replace whatever comes after the =?
    – Kusalananda
    May 12, 2023 at 7:28
  • I see your point. Yes you're right. However.. I have many devices each containing a unique identifier (10 digit code) in more than one place. The script I am preparing will allow for someone to set a new code in all the right files on a particular device. Only one of the files has the format 'code=1234567890'. In other places it is surrounded by different text but will always be a 10 digit number. So really I just want to match and replace a 10 digit number. So far the solutions provided do point me in the right direction. Many thanks May 12, 2023 at 7:50

5 Answers 5

5

sed uses Basic Regular Expression by default, meaning that {10} will be treated as plain text.

You can verify this :

echo "code=1{10}" | sed 's/[0-9]{10}/1234567890/'

Which will output :

1234567890

In your case, you need to either :

  • Use the -E option to specify that you want to use Extended Regular Expressions.
  • Escape { and } like this: \{10\}.
echo "code=1111111111" | sed -E 's/[0-9]{10}/1234567890/'
echo "code=1111111111" | sed 's/[0-9]\{10\}/1234567890/'
4

Using ERE regex flavor:

$ echo "code=1111111111" | sed -E 's/[0-9]{10}/1234567890/'
code=1234567890
4

Others have already pointed out that you are trying to use a POSIX extended regular expression with sed, which by default understands POSIX basic regular expressions. Some (most) implementations of the tool understand extended regular expressions if you use the -E option, but you could also change the expression to a basic one by changing {10} to \{10\}.

However, if you want to be sure that you replace the correct ten-digit number, you should probably avoid matching longer numbers and those that occur in other places in the input.

Without knowing more about the input, I would restrict the match by matching the = character and the end of the line:

sed 's/=[0-9]\{10\}$/=1234567890/'

This avoids matching longer numbers and ten-digit numbers that do not occur between a = and the end of the line.

If you know you need to change the value of the code variable (or whatever code is), also match that name (here, I'm also assuming the name starts at the start of the line, and I'm capturing the name and replacing it with \1 in the replacement to reduce duplication):

sed 's/^\(code\)=[0-9]\{10\}$/\1=1234567890/'
2

If you want to replace the first sequence of 10 and not more ASCII decimal digits with 1234567890 on each line, that should probably be:

sed -E 's/(^|[^0123456789])[0123456789]{10}([^0123456789]|$)/\112345678900\2/'

That is replace only 10 digits (using [0123456789] rather than [0-9] as the latter can match a lot more characters than just 0123456789 depending on the sed implementation and/or locale) preceded by either the beginning of the line or a non-digit and followed by either a non-digit or the end of the line.

That would still replace 1112223334.6 with 1234567890.6 or 1.0000000000e-2 with 1.1234567890e-2 or 0xff0777888999ee with 0xff1234567890ee so you may need to adapt depending on what you want and what you may find on the input.

To replace all the sequences of 10 and not more digits, that could be:

sed -E 's/[0123456789]+/\
&\
/g; s/\n[0123456789]{10}\n/123456789/g;s/\n//g'

Or you could switch to perl:

perl -pe 's/(?<!\d)\d{10}(?!\d)/1234567890/g'

Using the negative look-around operators to check that sequence of 10 decimal digits is neither preceded nor followed by another digit.

1

Thanks @Kamil Maciorowski

This works nicely

echo "code=1111111111" | sed 's/[0-9]\{10\}/1234567890/'
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .