【问题标题】:Replace control characters and spaces with escape sequences用转义序列替换控制字符和空格
【发布时间】:2013-10-23 16:33:25
【问题描述】:

我想用十六进制转义码替换控制字符(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。

【问题讨论】:

    标签: linux perl bash shell awk


    【解决方案1】:

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

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

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

    【讨论】:

    • 搞笑,我刚写的基本一样,正要投稿的时候看到你的。然后我正要对你的评论发表评论,并注意到当我看到你的编辑时它并没有完全正确地使用反斜杠:)
    【解决方案2】:

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

    这是我的 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]) )
    

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 他会想要s|\n|\\x0a
      • 澄清一下,换行符应该变成\\x0a,但是两个字符'\' + 'n'会变成\\n
      • 我要转义 34 个字符(32 个控制 + 空格 + 反斜杠)。我不想做 34 次搜索和替换。
      • 那么你花了多少个小时来尝试这样做而不是编写一个 34 行的 sed 脚本?
      猜你喜欢
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 2011-08-25
      • 2019-12-09
      • 1970-01-01
      • 2020-03-11
      相关资源
      最近更新 更多