Sed: extending a string of numbers to a certain number of digits by padding with zeros

This assumes that there is some non-numeric text after the number:

echo "loremipsumdolorsit2367amet" \
| sed -r -e 's/[0-9]/0000000&/' -e 's/0*([0-9]{8}[^0-9])/\1/'

Result: loremipsumdolorsit00002367amet

This doesn't assume that:

... | sed -r -e 's/[0-9]/0000000&/' -e 's/0*([0-9]{8}([^0-9]|$))/\1/'

These use the ERE patterns for sed. Many sed implementations use the -r flag to specify this; some use the -E flag; some use both. Currently the ability to use ERE patterns in sed is not part of the POSIX standard, but there's been talk of adding it to the standard. I haven't encountered a modern sed implementation which doesn't have the ability to use ERE patterns in one way or another.

In some cases there are things you can do using ERE patterns that you can't do using the default sed patterns (BREs). See the comments to this answer. But in the present case, the use of ERE patterns is just for convenience. As sch says in a comment, you can omit the -r (or -E) flag, and just replace the (...) with \(...\) and the {8} with \{8\}. My original answer made use of +, which is also not part of BRE patterns; but in fact this wasn't necessary to the solution.


With any sed:

sed 's/[0-9]\{1,\}/0000000&/g;s/0*\([0-9]\{8,\}\)/\1/g'

That's possible with perl:

perl -e 'my $a="loremipsumdolorsit2367amet"; $a =~ s/([0-9]+)/sprintf("%010d",$1)/e; print $a'

Got:

loremipsumdolorsit0000002367amet

To process all input lines:

perl -pe 's/([0-9]+)/sprintf("%010d",$1)/e'

Tags:

Sed