1

I have UUID, 3abbea88-c77d-11eb-b8bc-0242ac130003 and I want to take first 16 character of this string and want Hexadecimal string of first 16 characters using shell script.

I tried,

code=$(echo -n ${${ID##*:}:0:16} | od -A n -t x1)
HEX_ID=$(echo ${code//[[:blank:]]/})

Any better way ?

Expected Output : 33616262656138382d633737642d3131

Laleet
  • 41
  • 4
  • Why are you doing `${##*:}`? – KamilCuk Jun 07 '21 at 11:13
  • 2
    This code will grab the hypens (`-`) and get their hex code, resulting in a few `2d` entries, is that what you want? Or would you want to clear them and keep only the "first 16 relevant characters"? – vdavid Jun 07 '21 at 11:13
  • `${ID##*:}` looks like there is some text in front of your UUID that you didn't show in your question. Please edit your question to be consistent. – Socowi Jun 07 '21 at 11:14

5 Answers5

2

Using od you can simply limit the number of read characters using the -N option:

HEX_ID=$(od -A n -t x1 -N 16 <<< ${ID##*:} | tr -dc '[:xdigit:]')

Edit: tr is used to suppress non-hexadecimal characters, namely whitespaces and potential newlines.

vdavid
  • 2,434
  • 1
  • 14
  • 15
1

Perl to the rescue!

perl -le 'print unpack "H32", shift' 3abbea88-c77d-11eb-b8bc-0242ac130003
  • -l adds newlines to print
  • unpack takes a string and expands it to a list of values based on a template. H32 means "take characters and interpret them as 32 hex values".
  • shift reads the first command line argument.

Or, using xxd and head:

echo 3abbea88-c77d-11eb-b8bc-0242ac130003 | xxd -p | head -c32
choroba
  • 231,213
  • 25
  • 204
  • 289
  • I'm not a Perl expert but you say that H32 means "take 32 characters and interpret them as hex". If it was the case it would read 32 chars and output 64 hex numbers. I would assume that it first convert to hex and _then_ keep 32 characters, right? – vdavid Jun 07 '21 at 11:20
0

That's certainly a useless echo.

Probably avoid uppercase for your private variables.

uuid='3abbea88-c77d-11eb-b8bc-0242ac130003'
tmp=${uuid//-/}
hex_id=$(od -A n -t x1 <<<${tmp:0:13})
hex_id=${hex_id//[[:blank:]]/}
hex_id=${hex_id%0a}

The here string unattractively supplies trailing newline to od which we have to trim off.

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

Bash-only:

 while read -r -N 1 c                      # read input string 1 char at a time
 do [[ "$c" == " " ]] ||                   # skip embedded spaces
     printf "%02X" "$(                     # output the hexidecimal value of 
       printf "%d" \'$c                    # the ASCII decimal ordinal of $c
     )" 
 done <<< "${text##*:}"                    # ignoring the leading trash to the :
 echo                                      # newline-teminate the output

All in one line:

 while read -rn1 c;do [[ "$c" == " " ]]||printf %02X $(printf "%d" \'$c);done<<<"${text##*:}";echo

This is not the fastest approach...

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
0

hexdump does it all:

hexdump -n 16 -ve '1/1 "%.2x"'

-n 16 means only process the first 16 bytes
-e '1/1 "%.2x"' means display each byte using given printf format
-v means display normally (without this, it replaces dupe sections with * )


echo '3abbea88-c77d-11eb-b8bc-0242ac130003' | hexdump -n 16 -ve '1/1 "%.2x"'

output:

33616262656138382d633737642d3131
Bohemian
  • 412,405
  • 93
  • 575
  • 722