1

I'm trying to map a fixed set of ASCII characters to a fixed set of Unicode characters. I.e., for each digit 0-9, I want to get the circled digit equivalent.

mapFrom="0123456789"
mapTo="➀➁➂➃➄➅➆➇➈"

today=20221018

#convert to "➁➁➁➀➀➇"
todayWithCircles=$(do_something_here) # <-- what's the "something"?

echo $todayWithCircles
# output: ➁➁➁➀➀➇

Given two fixed strings of equal length, what is the easiest way to map them-- based on their position in the string-- as described?

Marc
  • 11,403
  • 2
  • 35
  • 45
  • There are a number of strategies for mapping to multi-byte keys in the post [Casing arrow keys in bash](https://stackoverflow.com/q/10679188/3422102) though they are usually mapping the reverse of what you need. However, if you have the unicode keycode for `➀➁➂➃➄➅➆➇➈`, you should be able to do the reverse map the same way using `case`. – David C. Rankin Oct 19 '22 at 02:33

2 Answers2

5

A quick and dirty approach using perl to do the translating:

#!/usr/bin/env bash

mapFrom="0123456789"
mapTo="➀➁➂➃➄➅➆➇➈"
today=20221018

perl -CSD -Mutf8 -pe "tr/$mapFrom/$mapTo/" <<<"$today"

outputs

➁➁➁➀➀➇

(Assuming the script is encoded in UTF-8, of course. -CSD tells perl to use UTF-8 encoding for standard input, output, and other opened files, -Mutf8 tells it that the script itself (The argument to -e) is encoded in UTF-8.)

If you have GNU sed available, you can use it instead:

sed "y/$mapFrom/$mapTo/" <<<"$today"

(See this unix stackexchange Q&A for why tr isn't suitable)

Shawn
  • 47,241
  • 3
  • 26
  • 60
1

Here's a bash only, pure way of doing this.

You loop over each character of the string, and replace it with a rounded character

#!/usr/bin/env bash

mapTo="➀➁➂➃➄➅➆➇➈"
today=0987654321

for ((i = 0; i < ${#today}; i++)); do
  echo -n "${mapTo:${today:$i:1}:1}"
done

result:

➈➇➆➅➄➃➂➁➀

Unamata Sanatarai
  • 6,475
  • 3
  • 29
  • 51
  • Thank you for this. The `sed` approach will work a little better for me than looping, but this is a great solution! – Marc Oct 20 '22 at 00:30