我想用十六进制转义码替换控制字符(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。
答案 0 :(得分:2)
这是我提出的Perl单线程。它使用/e
在替换中运行代码。
perl -pe 's/([\x00-\x20\\])/sprintf("\\x%02X", ord($1))/eg'
与我的问题中的示例略有偏差:它为反斜杠而不是\x5C
发出\\
。
答案 1 :(得分: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函数替换为预先构建的字典,将每个字符映射到所需的字符串表示。
答案 2 :(得分:-1)