【问题标题】:Trying to remove non-printable characters (junk values) from a UNIX file尝试从 UNIX 文件中删除不可打印的字符(垃圾值)
【发布时间】:2024-01-14 18:21:02
【问题描述】:

我正在尝试从我的文件中的记录中删除不可打印的字符(例如 ^@)。由于文件中的记录量太大,因此使用 cat 不是一个选项,因为循环花费了太多时间。 我尝试使用

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

^@ 字符仍然没有被删除。 我也尝试使用

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

但它也没有帮助。

谁能建议一些替代方法来删除不可打印的字符?

使用了tr -cd,但它正在删除重音字符。但它们在文件中是必需的。

【问题讨论】:

  • 使用哪种语言(unix参数)?
  • 已在 unix 框中创建了一个普通的 /bin/sh 脚本。该脚本将运行一个包含 2500 万条记录的文件,并从 db 中获取数据。但是,此脚本将省略具有垃圾值的记录。
  • 如果您看到很多 NULL (0x00, \0000) 字符,可能是某种多字节编码。 如果是这种情况,这些不是“垃圾”字符。 知道的最简单的检查方法是将文件或其中的一部分加载到emacs
  • 哎呀。我刚发现这个。我知道这会比emacs 快。 Check if file contains multibyte character

标签: bash unix awk sed non-printing-characters


【解决方案1】:

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

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

如果您的 tr 版本不支持多字节字符(似乎很多不支持),这对我来说适用于 GNU sed(使用 UTF-8 语言环境设置):

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

【讨论】:

    【解决方案2】:

    先删除所有控制字符:

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

    然后试试你的字符串:

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

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

    【讨论】:

      【解决方案3】:
      strings -1 file... > outputfile
      

      似乎有效。字符串程序将获取所有可打印字符,在这种情况下长度为 1(-1 参数)并打印它们。它有效地删除了所有不可打印的字符。

      “man strings”将提供文档。

      【讨论】:

      • 这个回复很短,没有最少的解释,所以它是删除的候选者。请尝试添加有关您建议的命令的更多说明。
      【解决方案4】:

      一直在寻找这个并找到了一个相当简单的解决方案:

      ansifilter 正是这样做的。你需要做的只是通过它来输出输出。

      在 Mac 上:

      brew install ansifilter

      然后:

      cat file.txt | ansifilter

      【讨论】: