我正在对 Linux 区域设置文件进行一些更改/usr/share/i18n/locales
(如 pt_BR),更改日期、时间、数字等的默认格式。但是由于 unicode 字符在<U9999>
格式,文本很难阅读。
这是其中的一个片段:
LC_TIME
abday "<U0044><U006F><U006D>";"<U0053><U0065><U0067>";/
"<U0054><U0065><U0072>";"<U0051><U0075><U0061>";/
"<U0051><U0075><U0069>";"<U0053><U0065><U0078>";/
"<U0053><U00E1><U0062>"
那么,如何制作一个简单的脚本(可能是 bash、python、pearl 等等)来转换此文本,替换<Uxxxx>
代码到它们的 ASCII 等价物? (是的,它们都是低于 255 的 ASCI 字符,大多数甚至低于 127)
如果收到多个答案,我将接受最优雅和/或更详细的解释(例如命令中使用的选项和标志)
例如,上面的文本将转换为:
LC_TIME
abday "Dom";"Seg";/
"Ter";"Qua";/
"Qui";"Sex";/
"Sáb"
另一个可以执行相反操作的脚本的奖励点:将给定字符串的所有字符转换为<Uxxx>
format.
Thanks!
使用字段
#!/bin/bash
awk -F'<U0+|>' '{
for(i=1;i<=NF;i++)
if($i ~ "^[0-9A-F]+$")
$i=sprintf("%c", strtonum("0x"$i))
}1' OFS="" /path/to/infile
解释
-F'<U0+|>'
:这就是这个脚本如此短的魔力。我们告诉 awk 字段分隔符是<U0+
或者一个简单的>
。这样做的好处是 awk 会自动为我们删除这些字符,因此我们不必手动执行此操作gsub()
当需要进行 strtonum() 转换时。
for(i=1;i<=NF;i++)
:迭代每个字段
-
if($i ~ "^[0-9A-F]+$")
:检查当前字段是否仅由十六进制数字组成。请记住,由于上面的#1,类似<U006F>
将被视为6F
在此刻
-
$i=sprintf("%c", strtonum("0x"$i))
:将十六进制数字替换为其对应的ascii值。我们必须为字段添加前缀$i
with "0x"
所以 awk 知道它是一个十六进制值
-
}1
: 强制的快捷方式print
or 总是打印每一行
-
OFS=""
:将输出字段分隔符设置为空字符串。如果我们不这样做,我们将在输出中出现空格的地方<U0+
or >
使用 match() [需要 gawk]
#!/bin/bash
gawk '{
while(match($0, /<U[0-9A-F]+>/)){
pat = substr($0,RSTART,RLENGTH)
gsub(/U0+|[<>]/,"",pat)
asc = sprintf("%c", strtonum("0x"pat))
$0 = substr($0, 1, RSTART-1) asc substr($0, RSTART+RLENGTH)
}
}1' /path/to/infile
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)