Artur Szymczak
Artur Szymczak

Reputation: 117

Add leading 0 in sed substitution

I have input data:

foo 24
foobar 5 bar
bar foo 125

and I'd like to have output:

foo 024
foobar 005 bar
bar foo 125

So I can use this sed substitutions:

s,\([a-z ]\+\)\([0-9]\)\([a-z ]*\),\100\2\3,
s,\([a-z ]\+\)\([0-9][0-9]\)\([a-z ]*\),\10\2\3,

But, can I make one substitution, that will do the same? Something like:

if (one digit) then two leading 0
elif (two digits) then one leading 0

Regards.

Upvotes: 8

Views: 13321

Answers (6)

Maksym Boyko
Maksym Boyko

Reputation: 21

Add the max number of leading zeros first, then take this number of characters from the end:

echo 55 | sed -e 's:^:0000000:' -e 's:0\+\(.\{8\}\)$:\1:'

00000055

Upvotes: 2

Blaf
Blaf

Reputation: 2310

I find the following sed approach to pad an integer number with zeroes to 5 (n) digits quite straighforward:

sed -e "s/\<\([0-9]\{1,4\}\)\>/0000\1/; s/\<0*\([0-9]\{5\}\)\>/\1/"
  1. If there is at least one, at most 4 (n-1) digits, add 4 (n-1) zeroes in front
  2. If there is any number of zeroes followed by 5 (n) digits after the first transformation, keep just these last 5 (n) digits

When there happen to be more than 5 (n) digits, this approach behaves the usual way -- nothing is padded or trimmed.

Input:

0
1
12
123
1234
12345
123456
1234567

Output:

00000
00001
00012
00123
01234
12345
123456
1234567

Upvotes: 1

potong
potong

Reputation: 58371

This might work for you (GNU sed):

echo '1.23 12,345 1 12 123 1234 1' | 
sed 's/\(^\|\s\)\([0-9]\(\s\|$\)\)/\100\2/g;s/\(^\|\s\)\([0-9][0-9]\(\s\|$\)\)/\10\2/g' 
1.23 12,345 001 012 123 1234 001

or perhaps a little easier on the eye:

sed -r 's/(^|\s)([0-9](\s|$))/\100\2/g;s/(^|\s)([0-9][0-9](\s|$))/\10\2/g'

Upvotes: 0

Thor
Thor

Reputation: 47099

You seem to have the sed options covered, here's one way with awk:

BEGIN      { RS="[ \n]"; ORS=OFS=""   }
/^[0-9]+$/ { $0 = sprintf("%03d", $0) } 
           { print $0, RT             }

Upvotes: 1

Lev Levitsky
Lev Levitsky

Reputation: 65791

I doubt that the "if - else" logic can be incorporated in one substitution command without saving the intermediate data (length of the match for instance). It doesn't mean you can't do it easily, though. For instance:

$ N=5
$ sed -r ":r;s/\b[0-9]{1,$(($N-1))}\b/0&/g;tr" infile
foo 00024
foobar 00005 bar
bar foo 00125

It uses recursion, adding one zero to all numbers that are shorter than $N digits in a loop that ends when no more substitutions can be made. The r label basically says: try to do substitution, then goto r if found something to substitute. See more on flow control in sed here.

Upvotes: 7

Birei
Birei

Reputation: 36262

Use two substitute commands: the first one will search for one digit and will insert two zeroes just before, and the second one will search for a number with two digits and will insert one zero just before. GNU sed is needed because I use the word boundary command to search for digits (\b).

sed -e 's/\b[0-9]\b/00&/g; s/\b[0-9]\{2\}\b/0&/g' infile

EDIT to add a test:

Content of infile:

foo 24 9
foo 645 bar 5 bar
bar foo 125

Run previous command with following output:

foo 024 009
foo 645 bar 005 bar
bar foo 125

Upvotes: 2

Related Questions