Bab*_*aba 16 bash unicode conversion
在波斯数字中,??????????相当于0123456789在欧洲数字中。
如何将波斯数字( in UTF-8)转换为 ASCII?
例如,我想??成为21.
cuo*_*glm 27
由于它是一组固定的数字,您可以手动完成:
$ echo ?? | LC_ALL=en_US.UTF-8 sed -e 'y/??????????/0123456789/'
21
Run Code Online (Sandbox Code Playgroud)
(或使用tr,但尚未使用GNU tr)
需要将您的语言环境设置为en_US.utf8(或更好地设置为字符集所属的语言环境)sed才能识别您的字符集。
与perl:
$ echo "??" |
perl -CS -MUnicode::UCD=num -MUnicode::Normalize -lne 'print num(NFKD($_))'
21
Run Code Online (Sandbox Code Playgroud)
phk*_*phk 15
对于 Python,有unidecode一个处理此类转换的库:https : //pypi.python.org/pypi/Unidecode。
在 Python 2 中:
>>> from unidecode import unidecode
>>> unidecode(u"??????????")
'0123456789'
Run Code Online (Sandbox Code Playgroud)
在 Python 3 中:
>>> from unidecode import unidecode
>>> unidecode("??????????")
'0123456789'
Run Code Online (Sandbox Code Playgroud)
/sf/ask/566116701/ 上的 SO 线程可能与此相关。
/ 编辑:正如 Wander Nauta 在评论中指出的,正如在 Unidecode 页面上提到的,还有一个 shell 版本unidecode(/usr/local/bin/如果安装在下面pip):
$ echo '??????????' | unidecode
0123456789
Run Code Online (Sandbox Code Playgroud)
纯 bash 版本:
#!/bin/bash
number="$1"
number=${number//?/1}
number=${number//?/2}
number=${number//?/3}
number=${number//?/4}
number=${number//?/5}
number=${number//?/6}
number=${number//?/7}
number=${number//?/8}
number=${number//?/9}
number=${number//?/0}
echo "Result is $number"
Run Code Online (Sandbox Code Playgroud)
已经在我的 Gentoo 机器上测试过,它可以工作。
./convert ???
Result is 132
Run Code Online (Sandbox Code Playgroud)
给定要转换的字符列表(从 0 到 9),作为循环完成:
#!/bin/bash
conv() ( LC_ALL=en_US.UTF-8
local n="$2"
for ((i=0;i<${#1};i++)); do
n=${n//"${1:i:1}"/"$i"}
done
printf '%s\n' "$n"
)
conv "??????????" "$1"
Run Code Online (Sandbox Code Playgroud)
并用作:
$ convert ???
132
Run Code Online (Sandbox Code Playgroud)
另一种(相当矫枉过正)方式使用grep:
#!/bin/bash
nums=$(echo "$1" | grep -o .)
result=()
for i in $nums
do
case $i in
?)
result+=1
;;
?)
result+=2
;;
?)
result+=3
;;
?)
result+=4
;;
?)
result+=5
;;
?)
result+=6
;;
?)
result+=7
;;
?)
result+=8
;;
?)
result+=9
;;
?)
result+=0
;;
esac
done
echo "Result is $result"
Run Code Online (Sandbox Code Playgroud)
小智 6
我们可以利用波斯数字的 UNICODE 代码点是连续的并且从 0 到 9 排序的事实:
$ printf '%b' '\U06F'{0..9}
??????????
Run Code Online (Sandbox Code Playgroud)
这意味着最后一个十六进制数字是十进制值:
$ echo $(( $(printf '%d' "'?") & 0xF ))
2
Run Code Online (Sandbox Code Playgroud)
这使得这个简单的循环成为一个转换工具:
#!/bin/bash
( ### Use a locale that use UTF-8 to make the script more reliable.
### Maybe something like LC_ALL=fa_IR.UTF-8 for you?.
LC_ALL=en_US.UTF-8
a="$1"
while (( ${#a} > 0 )); do
# extract the last hex digit from the UNICODE code point
# of the first character in the string "$a":
printf '%d' $(( $(printf '%d' "'$a") & 15 ))
a=${a#?} ## Remove one character from $a
done
)
echo
Run Code Online (Sandbox Code Playgroud)
将其用作:
$ sefr.sh ??????????
0123456789
$ sefr.sh ???
201
$ sefr.sh ??
21
Run Code Online (Sandbox Code Playgroud)
请注意,此代码还可以转换阿拉伯数字和拉丁数字(即使混合):
$ sefr.sh ?4??5??6??7??8??9?
444555666777888999
$ sefr.sh ??0??7??3????
4700671335667
Run Code Online (Sandbox Code Playgroud)