我有一个Shell脚本,可用于远程清理另一个系统生成的包含无效UNICODE字符的XML文件。我目前在脚本中使用此命令来删除无效字符:
perl -CSDA -i -pe's/[^\x9\xA\xD\x20-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]+//g;' file.xml
,到目前为止,此方法一直有效,但据我所知,该文件具有新错误,即“ xA0”,发生的是我的perl命令在文件中到达该错误并擦除了文件的其余部分。我修改了命令以包含xA0,但它不起作用:
perl -CSDA -i -pe's/[^\x9\xA0\xD\x20-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]+//g;' file.xml
我也尝试使用:
iconv -f UTF-8 -t UTF-8 -c file.xml > file2.xml
但是那什么也没做。它将产生具有相同错误的相同文件。
我可以使用可以完全删除所有无效UNICODE字符的unix命令吗?
编辑: 一些十六进制输出(请注意1A和A0):
3E 1A 1A 33 30 34 39 37 1A 1A 3C 2F 70
6D 62 65 72 3E A0 39 34 32 39 38 3C 2F
答案 0 :(得分:1)
您可以使用以下在线服务程序:
perl -i -MEncode -0777ne'print encode("UTF-8",decode("UTF-8",$_,sub{""}))' file.xml
您也可以使用警告对其进行扩展:
perl -i -MEncode -0777ne'print encode("UTF-8",decode("UTF-8",$_,sub{warn "Bad byte: @_";""}))' file.xml
答案 1 :(得分:1)
A0
不是有效的UTF-8序列。您遇到的错误是XML编码错误,而这是字符编码错误。
A0
是不间断空格的Unicode代码点。这也是该代码点的iso-8859-1和cp1252编码。
我建议从根本上解决问题。但是,如果那不可能,我建议使用Encoding::FixLatin来修复这种新型错误(也许通过捆绑的fix_latin
脚本)。它将用A0
(不间断空格的UTF-8编码)正确替换C2 A0
。
结合您现有的脚本:
perl -i -MEncoding::FixLatin=fix_latin -0777pe'
$_ = fix_latin($_);
utf8::decode($_);
s/[^\x9\xA\xD\x20-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]+//g;
utf8::encode($_);
' file.xml