0

I need help with a regular expression to expand any 1 character field to 2 characters with 0 padding. 0-9, a-f alphanumeric field.

Given:

echo $dhcp6_s46_cont_mapt 
0:5b:0:9:40:0:64:ff:9b:0:1:0:3:0:59:0:17:0:a:20:47:55:54:4c:36:26:0:6c:e1:80:e0:0:0:5d:0:4:1:0:0:0:

Expand to:

00:5b:00:09:40:00:64:ff:9b:00:01:00:03:00:59:00:17:00:0a:20:47:55:54:4c:36:26:00:6c:e1:80:e0:00:00:5d:00:04:01:00:00:00:

then remove colons (:) with:

updatedstring = ${dhcp6_s46_cont_mapt//:}

echo $updatedstring
005b0009400064ff9b000100 ... etc

Believe the answer should be along these lines: 's/ ([a-f0-9][a-f0-9][:])'|'s/([a-f0-9][:]) / 0\1 /' < $dhcp6_s46_cont_mapt --for the expansion search.

3

Why not keep everything in the (bash) shell?

$ dhcp6_s46_cont_mapt='0:5b:0:9:40:0:64:ff:9b:0:1:0:3:0:59:0:17:0:a:20:47:55:54:4c:36:26:0:6c:e1:80:e0:0:0:5d:0:4:1:0:0:0:'

$ IFS=: read -a arr <<<"$dhcp6_s46_cont_mapt"    
$ printf -v updatedstring '%02x' "${arr[@]/#/0x}"

$ echo "$updatedstring"
005b0009400064ff9b0001000300590017000a204755544c3626006ce180e000005d000401000000
| improve this answer | |
  • This works great in ubuntu, but I have an embedded linux busy box supported system. And I get a syntax error: # export new_dhcp6_s46_mapt=0:5b:0:9:40:0:64:ff:9b:0:1:0:3:0:59:0:17:0:a:20:47:55:54:4c:36:26:0:6c:e1:80:e0:0:0:5d:0:4:1:0:0:0 # printf -v updatedstring '%02x' "${arr[@]/#/0x}" -sh: syntax error: bad substitution – R. Gulde Oct 16 at 18:55
  • 2
    @R.Gulde that's expected - busybox sh is not SED/AWK/BASH... – steeldriver Oct 16 at 19:24
2

With POSIX sh syntax:

updatedstring=$(IFS=:; printf %02x $(printf 0x%s: $dhcp6_s46_cont_mapt))

A maybe unusual application of dd:

updatestring=$(
  printf %s "$dhcp6_s46_cont_mapt" |
    tr : '\n' |
    dd cbs=2 conv=block 2> /dev/null |
    tr ' ' 0
)
| improve this answer | |
0

using sed and character-class [[:xdigit:]] for hex digits only, you could do:

sed -E ':a s/(^|:)([[:xdigit:]])(:|$)/\10\2\3/; ta; s/://g'
  • [[:xdigit:]] matches on (0-9a-f; case insensitive)
| improve this answer | |
  • #! /bin/sh new_dhcp6_s46_cont_mapt=0:5b:0:9:40:0:64:ff:9b:0:1:0:3:0:59:0:17:0:a:20:47:55:54:4c:36:26:0:6c:e1:80:e0:0:0:5d:0:4:1:0:0:0 echo $new_dhcp6_s46_cont_mapt echo 'Run sed to expand' echo 'From:' echo $new_dhcp6_s46_cont_mapt echo 'To' x="$(echo $new_dhcp6_s46_cont_mapt | sed -E ':a s/(^|:)([[:xdigit:]])(:|$)/\10\2\3/; ta; s/://g')" echo "$x – R. Gulde Oct 16 at 19:40
0

Should work in busybox:

djunk=0:5b:0:9:40:0:64:ff:9b:0:1:0:3:0:59:0:17:0:a:20:47:55:54:4c:36:26:0:6c:e1:80:e0:0:0:5d:0:4:1:0:0:0:
djunk=$(djunk=:${djunk%:}; printf %02x ${djunk//:/ 0x})
echo "$djunk"

005b0009400064ff9b0001000300590017000a204755544c3626006ce180e000005d000401000000

Assuming default IFS, can be easily fixed (refinement left as an exercise to the reader)

| improve this answer | |
0

Using any awk in any shell on every UNIX box:

$ var='0:5b:0:9:40:a:b:64'
$ echo "$var" | awk 'BEGIN{FS=OFS=":"} {for (i=1;i<=NF;i++) $i=substr("0"$i,length($i))} 1'
00:5b:00:09:40:0a:0b:64

Otherwise, Using a sed that has -E to enable EREs:

$ var='0:5b:0:9:40:a:b:64'
$ echo "$var" | sed -E 's/(^|:)([^:])(:|$)/\10\2\3/g; s/(^|:)([^:])(:|$)/\10\2\3/g; s/://g'
005b0009400a0b64

here's what's happening in steps in the sed script:

$ echo "$var" | sed -E 's/(^|:)([^:])(:|$)/\10\2\3/g'
00:5b:00:9:40:0a:b:64

$ echo "$var" | sed -E 's/(^|:)([^:])(:|$)/\10\2\3/g; s/(^|:)([^:])(:|$)/\10\2\3/g'
00:5b:00:09:40:0a:0b:64

$ echo "$var" | sed -E 's/(^|:)([^:])(:|$)/\10\2\3/g; s/(^|:)([^:])(:|$)/\10\2\3/g; s/://g'
005b0009400a0b64
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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