使用sed无法删除不可打印的字符

问题描述 投票:1回答:1

我正在使用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的stackflow答案中使用UTF-8语言环境,这可行,但是我没有该语言环境。

也我正在使用ksh

unix sed ksh non-printing-characters
1个回答
0
投票

最简单-strings

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

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

此方法的问题:

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

最丑陋-sedl加上sed后处理

现在,如果必须使用sed,那么这是一种替代方法:

$ sed -n l /tmp/asdf | sed -E 's/\\[[:digit:]]{3}//g; s/\$$//'
in Arizona w/ fianc

[这里,您正在使用l来“转储”不可打印的字符,将它们转换为八进制表示形式,例如\303,然后删除任何看起来像八进制值的东西,然后删除$ l添加在该行的末尾。

这有点丑陋,并且可能与您的文件交互不良,如果它包含以反斜杠后跟三位数开头的任何内容,那么我将保留strings选项。

更好-sed具有高Unicode字符的范围

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

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

不幸的是,sed没有[[:ascii:]]范围。它都不接受开放式范围,因此您需要此技巧。

$ sed 's/[¡-ﺏ]/ /g' /tmp/asdf
in Arizona w/ fianc

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

© www.soinside.com 2019 - 2024. All rights reserved.