尝试从UNIX文件中删除非可打印字符(垃圾值)

12

我正在尝试从文件记录中删除不可打印字符(例如^@)。由于文件中记录的数量太多,所以使用cat命令不是一个选项,因为循环需要太长时间。 我尝试过使用

sed -i 's/[^@a-zA-Z 0-9`~!@#$%^&*()_+\[\]\\{}|;'\'':",.\/<>?]//g' FILENAME

但仍然没有去除^@字符。 同时我尝试使用

awk '{ sub("[^a-zA-Z0-9\"!@#$%^&*|_\[](){}", ""); print } FILENAME > NEW FILE 

但它也没有帮助。

有人能建议一些替代的方法来删除非打印字符吗?

使用tr -cd但它会删除重音符号。但是文件中需要它们。


使用哪种语言(Unix 参数)? - NeronLeVelu
已在Unix系统中创建一个普通的/bin/sh脚本。此脚本将在一个包含2500万记录的文件上运行,并从数据库中提取数据。但是,该脚本会忽略掉具有垃圾值的记录。 - Pranav
如果你看到很多NULL(0x00,\0000)字符,那可能是一种多字节编码。如果是这种情况,这些并不是"垃圾"字符。 我所知道最简单的检查方法就是将文件或部分内容加载到emacs中。 - Erik Bennett
面向对象编程。我刚发现这个。我 知道 这比 emacs 更快。检查文件是否包含多字节字符 - Erik Bennett
4个回答

24

也许您可以使用 [:print:] 的补集,其中包含所有可打印字符:

tr -cd '[:print:]' < file > newfile

如果您使用的 tr 版本不支持多字节字符(似乎很多版本都不支持),那么使用 GNU sed(在 UTF-8 区域设置下)可以解决我的问题:

sed 's/[^[:print:]]//g' file

1
在 Mac 上,您需要使用 gsed - Hritik

4

首先删除所有控制字符:

tr -dc '\007-\011\012-\015\040-\376' < file > newfile

然后尝试您的字符串:
sed -i 's/[^@a-zA-Z 0-9`~!@#$%^&*()_+\[\]\\{}|;'\'':",.\/<>?]//g' newfile

我相信你看到的^@实际上是零值\0
上面的tr过滤器也会将其删除。


0

我曾经寻找了一段时间,最终找到了一个相当简单的解决方案:

ansifilter正好可以做到这一点。你只需要将输出通过它进行管道传输即可。

在Mac上:

brew install ansifilter

然后:

cat file.txt | ansifilter


也适用于Linux。谢谢!其他解决方案对我没有用,因为我想要转换字符串 "\033[?1002l\033[?1000l\033[?1005l\033[?2004h\033[?2004l\033[?1002l\033[?1000l\033[?1005ldebconf:" (\033 是转义字符,类似于 \e)。 - L_R

0
strings -1 file... > outputfile

看起来工作正常。字符串程序将获取所有可打印字符,本例中长度为1(-1参数),并将它们打印出来。实际上,它正在删除所有不可打印的字符。

“man strings”将提供文档。


1
这个回复非常简短,缺乏最基本的解释,因此可能会被删除。请尝试添加一些关于你建议的命令的更多解释。 - linuxfan says Reinstate Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接