从Unix中的utf-8文件中删除垃圾字符

时间:2017-01-17 14:39:38

标签: shell unix unicode strip null-character

我得到了垃圾字符(<9f><9d><9d>等),CNTRL字符(^Z^M等)和NULL字符(^@)在文件中。但是,我能够从文件中删除CNTRLNULL个字符,但无法消除垃圾字符。谁能建议一种方法来删除这些垃圾字符?

Screen shot for Junk Data

使用以下命令删除控制字符:

sed 's/\x1a//g;s/\xef\xbf\xbd//g'

使用以下命令删除空字符

tr -d '\000'

另外,请建议单一命令删除所有上述3种类型的garbal字符。

先谢谢

1 个答案:

答案 0 :(得分:1)

剥离“不寻常”的unicode字符

在评论中你提到你想要在保留希腊字符时阻止控制字符,所以下面的tr解决方案不适合。一个解决方案是sed,它提供unicode支持,并且它们的[[:alpha:]]类也匹配ascii之外的字母字符。您首先需要设置LC_CTYPE以指定哪些字符都属于[[:alpha:]]范围。对于带有变音符号的德语,就是这样的。

LC_CTYPE=de_DE.UTF-8

然后你可以使用sed删除所有不是字母或标点符号的内容:

sed 's/[^[:alpha:];\ -@]//g' < junk.txt

\ -@的作用:它匹配空格和@之间的ascii范围内的所有字符(请参阅ascii table .Sed有[[:punct:]]类,但不幸的是,这也匹配很多垃圾,所以需要\ -@

您可能需要使用LC_CTYPE进行一些游戏,将其设置为utf-8,但我只能匹配希腊字符,而不是日语字符。

如果你只关心ascii

如果您只关心常规的ascii字符,可以使用tr:首先,您将文件转换为“每个字符一个字节”编码,因为tr不理解多字节字符,例如使用iconv

然后,我建议您使用白名单方法(与您在问题中的黑名单方法相对),因为要说明要保留的内容要比过滤出来的要容易得多。

此命令应该这样做:

iconv -c -f utf-8 -t latin1 < junk.txt | tr -cd '\11\12\40-\176'

这一行..

  • 转换为latin1(每个字符单个字节)并忽略代码点127上方的所有字符(这是特殊字符,但要注意,这也会删除您可能想要保留的语言中的变音符号或特殊字符等内容! )
  • 剥离此白名单之外的所有字符:\11\12\40-\176。那里的数字是八进制的。看看例如this ascii table\11tab\12为回车。 \40-\176是通常被视为“正常”的所有字符