2013-10-23 29 views
0

我想用十六進制轉義碼替換控制字符(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。

回答

2

下面是我提出的Perl單線程。它使用/e在替代品中運行代碼。

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

從我關注的例子稍有偏差:它發出\x5C的反斜槓,而不是\\

+1

有趣的是,我只是寫了基本相同的東西,並且當我看到你的時候就要提交它。然後,我正要對你的評論,並注意到,當我看到你的編輯:)它不會反斜槓)。 – hobbs

-1

哇,它看起來像一個相當簡單的sed腳本,沿着 's|\n|\\n|'的行,你想替換每個字符。

+2

他會想's \ n | \\ x0a'來代替。 – chepner

+1

爲了澄清,換行符應該變成'\\ x0a',但是兩個字符'\'+'n'會變成'\\ n'。 – chepner

+2

我想逃避34個字符(32位控制+空格+反斜槓)。我不想做34搜索和替換。 –

0

我會使用更高級的語言。有三種不同類型的替換正在進行(控制字符和空格的單字符到多字符,其他可打印字符的標識以及加倍反斜線的特殊情況),我認爲這對於awksedsed來說太多了。喜歡簡單處理。

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

方法,如果速度是一個問題,您可以使用預置的字典映射每個字符替換翻譯功能,其所需的字符串表示。