我从文件中提取数据(在这种情况下是一个exim邮件日志),并且通常会将字符保存在转义的八进制序列中,例如\ NNN,其中' N' N' N'表示八进制值0-7。这主要发生在主题以非拉丁字符(例如阿拉伯语)编写时。
我的目标是找到最简单的方法来转换这些八进制字符,以便在我的utf-8启用的终端中正确显示,特别是在&less;' less'因为有很多输出的可能性。
到目前为止,我发现的最佳方法如下:
arbitrary_stream | { while read -r temp; do printf %b "$temp\n"; done } | less
这似乎工作得很好,但是我会假设有一些翻译工具,或者甚至可能是一个内置于“少”的翻译工具。处理这个。我还发现,如果你使用像sed之类的东西在每个\之后注入0,你可以将它存储为变量,然后使用' echo -e $ data'然而,这比之前的解决方案更加混乱。
测试用例:
octalvar="\342\202\254"
预期产量减少:
€
我正在寻找更清洁,更完整或更好的东西,而不仅仅是上述解决方案:
echo $octalvar | do_something | less
或
echo $octalvar | less --some_magic_flag
有什么建议吗?或者我的解决方案是否像我期望的一样干净?
答案 0 :(得分:0)
这是我目前的版本:
echo $arbitrary | { IFS=$'\n'; while read -r temp; do printf %b "$temp\n"; done; unset IFS; } | iconv -f utf-8 -t utf-8 -c | less
答案 1 :(得分:0)
GNU awk中的转换(使用strtonum
)。它被证明是一个麻烦所以代码是一团糟,也许可以简化,随意建议:
awk '{
while(match($0,/\\[0-8]{3}/)) { # search for \NNNs
o=substr($0,RSTART,RLENGTH) # extract it
sub(/\\/,"0",o) # replace \ with 0 for strtonum
c=sprintf("%c",strtonum(o)) # convert to a character
sub(/\\[0-8]{3}/,c) # replace the \NNN with the char
}
}1' foo > bar
或将单引号之间的代码粘贴到文件above_program.awk
,然后像awk -f above_program.awk foo > bar
一样运行。测试文件foo
:
test 123 \342\202\254
在非UTF8语言环境中运行它,我使用语言环境C:
$ locale
...
LC_ALL=C
$ awk -f above_program.awk foo
test 123 €
如果您运行UTF8语言环境,则会发生转换:
$ locale
...
LC_ALL=en_US.utf8
$ awk -f above_program.awk foo
test 123 â¬