1

我想用十六进制转义码替换控制字符(ASCII 0-31)和空格(ASCII 32)。例如:

$ escape 'label=My Disc'
label=My\x20Disc
$ escape $'multi\nline\ttabbed string'
multi\x0Aline\x09tabbed\x20string
$ escape '\'
\\

就上下文而言,我正在编写一个状态为 DVD 驱动器的脚本。它的输出被设计为由另一个程序解析。我的想法是将每条信息打印为一个单独的空格分隔的单词。例如:

$ ./discStatus --monitor
/dev/dvd: no-disc
/dev/dvd: disc blank writable size=0 capacity=2015385600
/dev/dvd: disc not-blank not-writable size=2015385600 capacity=2015385600

我想将光盘的标签添加到此输出中。为了适应解析方案,我需要转义空格和换行符。我也可以做所有其他控制字符。

如果可能的话,我更愿意坚持使用 bash、sed、awk、tr 等。不过,我想不出一种真正优雅的方式来使用这些工具来做到这一点。如果基本的 shell 结构和工具没有好的解决方案,我愿意使用 perl 或 python。

4

3 回答 3

2

这是我想出的 Perl 单行代码。它用于/e在替换中运行代码。

perl -pe 's/([\x00-\x20\\])/sprintf("\\x%02X", ord($1))/eg'

与我的问题中的示例略有不同:它发出\x5C反斜杠而不是\\.

于 2013-10-23T18:24:01.350 回答
0

我会使用更高级的语言。awk正在进行三种不同类型的替换(控制字符和空格的单字符到多字符,其他可打印字符的标识,以及加倍反斜杠的特殊情况),我认为这对于,sed等来说太多了处理简单。

这是我的 Python 方法

def translate(c):
    cp = ord(c)
    if cp in range(33):
        return '\\x%02x'%(cp,)
    elif c == '\\':
        return r'\\'
    else:
        return c

if __name__ == '__main__':
    import sys
    print ''.join( map(translate, sys.argv[1]) )

如果速度是一个问题,您可以使用预构建的字典替换 translate 函数,将每个字符映射到其所需的字符串表示形式。

于 2013-10-23T17:26:16.453 回答
-1

's|\n|\\n|'哇,对于要替换的每个字符,它看起来像是一个相当简单的 sed 脚本 。

于 2013-10-23T16:39:03.023 回答