我正在对Linux语言环境文件/usr/share/i18n/locales
进行一些更改(如pt_BR
),并且必须在Unicode中指定格式字符串(如%d-%m-%Y %H:%M
),其中每个(在这种情况下,ASCII)字符表示为<U00xx>
。
所以这样的文字:
LC_TIME
d_t_fmt "%a %d %b %Y %T %Z"
d_fmt "%d-%m-%Y"
t_fmt "%T"
必须:
LC_TIME
d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
d_fmt "<U0025><U0064><U002D><U0025><U006D><U002D><U0025><U0059>"
t_fmt "<U0025><U0054>"
因此,我需要一个命令行脚本(无论是bash,Python,Perl还是其他),它会接受%d-%m-%Y
之类的输入并将其转换为<U0025><U0064><U002D><U0025><U006D><U002D><U0025><U0059>
。
输入字符串中的所有字符都是ASCII字符(从0x20
到0x7F
),所以这实际上是一个更加绚丽的“char-to-hex-string”转换。
有人可以帮帮我吗?我在bash脚本编写方面的技能非常有限,在Python中甚至更糟。
优雅,解释的解决方案的奖金。
谢谢!
(顺便说一下,这将是我previous question)
的“反向”脚本答案 0 :(得分:7)
如果你想将文件的每个字符转换为unicode表示,那么这就是这个简单的单行
while IFS= read -r -n1 c;do printf "<U%04X>" "'$c"; done < ./infile
如果你想制作一个类似于unix的工具,将STDIN上的输入转换为类似unicode的输出,那么使用它:
uni(){ c=$(cat); for((i=0;i<${#c};i++)); do printf "<U%04X>" "'${c:i:1}"; done; }
$ echo "abc" | uni
<U0061><U0062><U0063>
#!/bin/bash
flag=0
while IFS= read -r -n1 c; do
if [[ "$c" == '"' ]]; then
((flag^=1))
printf "%c" "$c"
elif [[ "$c" == $'\0' ]]; then
echo
elif ((flag)); then
printf "<U%04X>" "'$c"
else
printf "%c" "$c"
fi
done < /path/to/infile
$ cat ./unime
LC_TIME
d_t_fmt "%a %d %b %Y %T %Z"
d_fmt "%d-%m-%Y"
t_fmt "%T"
abday "Dom";"Seg";/
here is a string with "multiline
quotes";/
$ ./uni.sh
LC_TIME
d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
d_fmt "<U0025><U0064><U002D><U0025><U006D><U002D><U0025><U0059>"
t_fmt "<U0025><U0054>"
abday "<U0044><U006F><U006D>";"<U0053><U0065><U0067>";/
here is a string with "<U006D><U0075><U006C><U0074><U0069><U006C><U0069><U006E><U0065>
<U0071><U0075><U006F><U0074><U0065><U0073>";/
非常简单
while IFS= read -r -n1 c;
:一次迭代输入的一个字符(通过-n1
)并将char存储在变量c
中。 IFS=
和-r
标志位于此处,因此read
内置函数不会分别尝试进行单词拆分或解释转义序列。 if [[ "$c" == '"' ]];
:如果当前字符是双引号((flag^=1))
:从0-> 1或1-> 0 elif [[ "$c" == $'\0' ]];
:如果当前的字符是NUL,那么echo
换行符elif ((flag))
:如果flag为1,则执行unicode transliteration printf "<U%04X>" "'$c"
:执行unicode音译的魔力。请注意,$c
之前的单引号是必需的,因为它告诉printf
我们正在为它提供数字的ASCII表示。else printf "%c" "$c"
:打印出没有执行unicode音译的角色答案 1 :(得分:5)
#!/usr/bin/env python3.2
import sys
text = sys.argv[1]
encoded = "".join("<U{0:04X}>".format(ord(char)) for char in text)
print(encoded)
用法:
$ python3 file.py "enter_input"
<U0065><U006E><U0074><U0065><U0072><U005F><U0069><U006E><U0070><U0075><U0074>
(同样的脚本应该适用于python 3.x和2.x.只需更改shebang中的版本即可 你拥有的那个。)
说明:
我们需要导入the sys
module来读取命令行参数。
sys.argv
list是所有命令行参数的列表。条目[0]是程序名称,条目[1]是第一个参数,等等。
f(char) for char in text
是generator expression。它将为text
变量中的每个字符循环,然后在其上应用函数f
,最后将结果作为惰性列表(iterable)收集。
ord(char)
找到角色的Unicode代码点。
"<U{0:04X}>".format(x)
是一个字符串格式化方法,如名称所述。格式字符串采用1个输入x
,并格式化为04X
format,表示前导零,宽度为4,大写十六进制。
"".join(it)
连接延迟列表中的所有元素(可迭代)it
。 ""
表示分隔符是空字符串。
print(encoded)
将字符串encoded
写入stdout。
答案 2 :(得分:0)
echo -n "aä" | ruby -KU -e '$<.chars{|c| print "<U"+"%04X"%c.unpack("U*")[0]+">"}; puts'
输出<U0061><U00E4>
-KU
= $KCODE = "U"
答案 3 :(得分:0)
Shell脚本解决方案:
#!/bin/sh
while IFS= read -r -n1 c;
do printf "<U%04X>" "'$c";
done
这会读取标准输入并打印到标准输出(假设您已将脚本放入可执行文件 toUnicode.sh ):
> echo "hello" | toUnicode.sh
<U0068><U0065><U006C><U006C><U006F><U0000>
这会打印EOF字符(<U0000>
),但您可以更改此脚本以满足您的需要,无论您是想一次读取一行还是修改它或以其他方式改变它。