2017-04-17 67 views
0

我正在從文件中提取數據(在本例中爲一個exim郵件日誌),並且經常將字符保存爲轉義的八進制序列,如\ NNN,其中'N'表示八進制值爲0-7。當主題用非拉丁字符(例如阿拉伯語)書寫時,主要發生這種情況。Unix - 如何通過管道轉換八進制轉義序列

我的目標是找到最簡潔的方法來轉換這些八進制字符,以在啓用utf-8的終端中正確顯示,特別是在'less'中,因爲有很多輸出的潛力。

到目前爲止,我已經找到了最好的方法如下:

arbitrary_stream | { while read -r temp; do printf %b "$temp\n"; done } | less 

這似乎是工作得很好,但我會假設有一些翻譯工具,或者甚至一個標誌建成「少'來處理這個問題。我還發現,如果你使用類似sed的東西在每個\之後注入0,則可以將它作爲變量存儲,然後使用'echo -e $ data',但這比以前的解決方案更加混亂。

測試用例:在

octalvar="\342\202\254" 

預計產量不足:

我在尋找的東西更清潔,更完整的或只是比我在任何形式上面更好的解決方案:

echo $octalvar | do_something | less 

echo $octalvar | less --some_magic_flag 

有什麼建議嗎?或者我的解決方案和我所期望的一樣乾淨?

+0

每個字符都是八進制格式嗎? – 123

+1

不,這是一個正常的文本和八邊形溢出 – user1869743

+1

你的解決方案是probs你會得到最好的,然後少,沒有一個標誌將八進制轉換爲ascii。也許改爲'while IFS = read -r temp'來保存空格。 – 123

回答

0

這是我目前的版本:

echo $arbitrary | { IFS=$'\n'; while read -r temp; do printf %b "$temp\n"; done; unset IFS; } | iconv -f utf-8 -t utf-8 -c | less 
0

轉換在GNU AWK(使用strtonum)。它被證明了是一個麻煩所以代碼是一個爛攤子,也許可以簡化,可隨時諮詢:

awk '{ 
    while(match($0,/\\[0-8]{3}/)) { # search for \NNNs 
     o=substr($0,RSTART,RLENGTH) # extract it 
     sub(/\\/,"0",o)    # replace \ with 0 for strtonum 
     c=sprintf("%c",strtonum(o)) # convert to a character 
     sub(/\\[0-8]{3}/,c)   # replace the \NNN with the char 
    } 
}1' foo > bar 

或單引號之間的代碼粘貼到一個文件above_program.awk和喜歡awk -f above_program.awk foo > bar運行它。測試文件foo:在非UTF8語言環境

test 123 \342\202\254 

運行它,我用的語言環境C:

$ locale 
... 
LC_ALL=C 
$ awk -f above_program.awk foo 
test 123 € 

如果你運行一個UTF8區域設置,轉換會發生:

$ locale 
... 
LC_ALL=en_US.utf8 
$ awk -f above_program.awk foo 
test 123 ⬠
相關問題