如何在Bash(linux)或Python上只过滤文件中的可打印字符?

2024-10-02 12:31:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使一个文件包括不可打印字符,只包括可打印字符。我认为这个问题与ACSCII control action有关,但我找不到解决方法,也无法理解.[16D(ASCII控制操作字符??)的含义在下面的文件中。在

输入文件的十六进制转储:

00000000: 4845 4c4c 4f20 5448 4953 2049 5320 5448 HELLO THIS IS TH
00000010: 4520 5445 5354 1b5b 3136 4420 2020 2020 E TEST.[16D
00000020: 2020 2020 2020 2020 2020 201b 5b31 3644            .[16D
00000030: 2020

当我catbash上编辑了那个文件,我只得到了一个消息:“你好”。我认为这是因为默认的cat解释了ASCII控制操作,两个.[16D

为什么两个.[16D字符串组成cat文件只是为了打印“HELLO”?,还有。。。如何使该文件仅包含可打印字符,即“HELLO”?在


Tags: 文件方法testbashhelloisasciiaction
3条回答

我想到的最简单的解决方案是

import string
printable_string = filter(lambda x: x in string.printable, your_string)
## TODO: substitute your string in the place of "your_string"

如果这仍然没有帮助,那么尝试也包括uni代码特定的[诅咒.ascii]在

hexdump显示.[16D中的点实际上是转义符,\x1b
Esc[nD是删除n字符的ANSI escape code。因此Esc[16D告诉终端删除16个字符,这解释了cat输出。在

从文件中删除ANSI转义码有多种方法,可以使用Bash命令(例如使用sed,如Anubhava的回答)或Python。在

但是,在这种情况下,最好通过终端仿真器运行该文件,以解释文件中任何现有的编辑控制序列,这样在应用这些编辑序列之后,您就可以得到文件作者想要的结果。在

在Python中实现这一点的一种方法是使用pyte,这是一个Python模块,它实现了一个简单的与VTXXX兼容的终端仿真器。您可以使用pip轻松地安装它,下面是它在readthedocs上的文档。在

下面是一个简单的演示程序,它解释问题中给出的数据。它是为python2编写的,但是很容易适应python3。pyte支持Unicode,它的标准流类需要Unicode字符串,但是这个示例使用了ByteStream,所以我可以向它传递一个纯字节字符串。在

#!/usr/bin/env python

''' pyte VTxxx terminal emulator demo

    Interpret a byte string containing text and ANSI / VTxxx control sequences

    Code adapted from the demo script in the pyte tutorial at
    http://pyte.readthedocs.org/en/latest/tutorial.html#tutorial

    Posted to http://stackoverflow.com/a/30571342/4014959 

    Written by PM 2Ring 2015.06.02
'''

import pyte


#hex dump of data
#00000000  48 45 4c 4c 4f 20 54 48  49 53 20 49 53 20 54 48  |HELLO THIS IS TH|
#00000010  45 20 54 45 53 54 1b 5b  31 36 44 20 20 20 20 20  |E TEST.[16D     |
#00000020  20 20 20 20 20 20 20 20  20 20 20 1b 5b 31 36 44  |           .[16D|
#00000030  20 20                                             |  |

data = 'HELLO THIS IS THE TEST\x1b[16D                \x1b[16D  '

#Create a default sized screen that tracks changed lines
screen = pyte.DiffScreen(80, 24)
screen.dirty.clear()
stream = pyte.ByteStream()
stream.attach(screen)
stream.feed(data)

#Get index of last line containing text
last = max(screen.dirty)

#Gather lines, stripping trailing whitespace
lines = [screen.display[i].rstrip() for i in range(last + 1)]

print '\n'.join(lines)

输出

^{pr2}$

输出的十六进制转储

00000000  48 45 4c 4c 4f 0a                                 |HELLO.|

您可以尝试使用sed命令从文件中删除所有不可打印的字符:

sed -i.bak 's/[^[:print:]]//g' file

相关问题 更多 >

    热门问题