2016-11-18 105 views
1

我想將二進制文件轉換爲十六進制的ASCII表示形式。這實際上是由於分享我的學術工作時出現了一個奇怪的可移植性問題。動機是,以十六進制表示的文件更容易以ASCII格式打印大值。我有我擁有BASH的獨特情況,但可能沒有xxd或hexdump。我試圖製作一個bash腳本,它接受一個文件,讀取一個字節,然後以ASCII十六進制格式輸出一個值。我認爲printf會是要走的路,但是如果文件有二進制0x30,它會打印出ASCII碼「0」。Bash,將字節轉換爲ASCII而不使用hexdump或xxd

#!/bin/sh 
INPUTFILE=$1 
while IFS= read -r -n1 filechar 
do 
    printf "%02X" "$filechar" 
done < "$INPUTFILE" 
printf "\n" 

我不清楚爲什麼 「%02X」 沒有返回 「30」 爲 「0」 的ASCII值。再一次,問題的真正關鍵是我試圖只使用Bash,因爲我不能保證任何人都有Bash。更糟糕的是,我正在嘗試使用Bash 3.x.任何建議將是最受歡迎的。

+2

打印'0'的原因是因爲這是它正在讀取的值。您正在讀取文件中的每個字符,因此'filechar'值的值爲0. printf'二進制不會將您傳遞給它的字符解釋爲數字。你不能使用'od -tx $ INPUTFILE'?這應該是POSIX友好的。 – eddiem

+0

@eddiem也許吧。想象一個如此安全以至於無法使用的系統。這就是爲什麼我試圖用bash來做所有事情的原因,就像那樣。這只是一個管道噩夢。 「od」是一個不錯的選擇,因爲它永遠存在。直到你提到它,我才知道od。如果我能確定每個人都可以運行,我會問管理員。 –

+0

對於某些字符值,您將遇到一些問題:字符0(ASCII NULL)不能在shell變量中表示或作爲參數傳遞,並且127(十六進制7f)以上的字符可能會有問題,具體取決於您的語言環境。 –

回答

0

我想通了一種方法,儘管加載文件到一個字符串可怕。

#!/bin/sh 
FILESTRING=$(<$1) 
for ((i=0;i<${#FILESTRING};i++)); 
do 
    printf %02X \'${FILESTRING:$i:1}; 
done 

在這種方法中,我不需要外部可執行,所以我不擔心猛砸以外的任何東西。感謝所有評論過的人。

1

如果字符前面有撇號,則使用該字符的ASCII值。

printf "%02X" "'$filechar" 

但是,我不認爲這將適用於非ASCII(> 127)字符。