删除sed无法正常工作的不可打印字符

时间:2018-09-25 18:22:49

标签: unix sed ksh non-printing-characters

我正在使用AIX Unix并尝试从文件中删除不可打印的字符,当我使用UTF-8编码在Notepad ++中查看时,文件中的数据看起来像in Arizona w/ fiancÃÂÃÂÃÂ。当我尝试在Unix中查看文件时,我得到^▒▒^▒▒^^▒▒^▒▒^▒▒^▒▒

我想用空格替换所有那些特殊字符,我的输出应类似于in Arizona w/ fianc

我尝试了sed 's/[^[:print:]]/ /g' file,但是并没有删除那些字符。运行locale -a时会在下面列出我的语言环境

C
POSIX
en_US.8859-15
en_US.ISO8859-1
en_US

我什至尝试了sed -e 's/[^ -~]/ /g',但它没有删除字符。

我看到其他堆栈流答案在GNU sed中使用UTF-8语言环境,这可行,但是我没有该语言环境。

我也在使用ksh

1 个答案:

答案 0 :(得分:0)

最简单-strings

最简单的方法是使用strings命令:

$ cat  /tmp/asdf
in Arizona w/ fiancÃÂÃÂÃÂ
$ strings  /tmp/asdf
in Arizona w/ fianc

这种方法的问题:

  • 它没有使用sed
  • 只要找到任何不可打印的字符,它都会添加一行结尾(在您的示例中应该可以,因为它们都在末尾分组,否则会失败)

最丑陋-sed的{​​{1}}加上l后处理

现在,如果您必须使用sed,那么可以选择以下方法:

sed

在这里,您使用$ sed -n l /tmp/asdf | sed -E 's/\\[[:digit:]]{3}//g; s/\$$//' in Arizona w/ fianc 来“转储”不可打印的字符,将它们转换为l之类的八进制表示形式,然后删除任何看起来像这样创建的八进制值的东西,然后删除\303在行尾添加的$

有点丑陋,如果文件中包含反斜杠后跟三位数字的文件,则可能与文件交互不良,因此我将继续使用l选项。

更好-strings的Unicode字符范围高

下面的那个也是一个hack,但是看起来比其他更好。它使用sed范围,以'¡'开头。我之所以选择该符号,是因为它是iso-8859-1编码中的第二个*字符,它恰好也是ASCII之后的Unicode部分。因此,我猜测您在使用实际的控制代码时不会遇到麻烦,但是可以使用非ASCII字符(超过127个十进制的任何字符)代替。

对于范围中的第二项,只需选择一些非拉丁字符(日语,中文,希伯来语,阿拉伯语等),希望它在Unicode中足够高,可以包含您的任何“非打印”字符

很遗憾,sed没有sed范围。它都不接受开放式范围,因此您需要此技巧。

[[:ascii:]]

(*)注:我选择了范围中的第二个字符,因为第一个字符是不间断的空格,因此很难理解它不仅是正常的空格。