2009-10-22 208 views
42

可以說我有一個字符串5a。這是ASCII 字母Z的十六進制表示。我需要知道一個Linux shell命令,它將採用十六進制字符串 並輸出字符串表示的二進制字節。linux shell腳本:十六進制字符串到字節

所以,如果我做

echo 5a | command_im_looking_for > temp.txt 

和我開temp.txt,我會看到一個孤立的字母Z

回答

52
echo -n 5a | perl -pe 's/([0-9a-f]{2})/chr hex $1/gie' 

注意,這不會跳過非十六進制字符。如果你只想十六進制(沒有從原來的字符串等空格):

echo 5a | perl -ne 's/([0-9a-f]{2})/print chr hex $1/gie' 

此外,zshbash支持這一本身在echo

echo -e '\x5a' 
+0

你可能需要把「我」後的正則表達式那裏。 – 2009-10-22 02:57:34

+0

哎呦,謝謝:) – bdonlan 2009-10-22 02:58:13

+0

或者把a-fA-F放在字符類中。 – 2009-10-22 02:58:33

1
echo 5a | python -c "import sys; print chr(int(sys.stdin.read(),base=16))" 
+0

將'print'更改爲'sys.stdout.write'以防止多餘的換行字符。 – nobar 2013-07-10 19:46:43

-3

OD -c 或 hexdump -c

+4

不,這會轉換到另一個方向(字符爲八進制或十六進制)。 – 2009-10-22 07:09:40

+0

檢查語法。 -c給出字符輸出。 -a只給ascii。我通常用它來查看未知文件,例如「od -c filename | more」,它會將文件以可讀的字符傾倒出來 – james 2009-10-22 12:44:56

+2

您能否提供一個可用的示例?看起來,這會以字符形式轉儲輸入流,但不會將基於十六進制的數字作爲輸入 - 因此它不提供所需的功能。 – nobar 2013-07-10 19:51:11

3

根據你得到那個「5a」的位置,你可以直接追加\ x並傳遞給printf

$ a=5a 
$ a="\x${a}" 
$ printf "$a" 
Z 
+3

第二行和第三行可以合併爲一個:'printf'\ x $ {a}「' – 2009-10-22 07:11:50

64

用來做此使用XXD

echo -n 5a | xxd -r -p 

但是,我意識到,在於Debian/Ubuntu,XXD是VIM-共同的一部分,因此可能不存在於一個最小的系統。也避免Perl的(恕我直言,還沒有一個最小系統的一部分),我結束了使用SED,xargs的和printf這樣的:

echo -n 5a | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf 

主要是我只是想轉換幾個字節,它的好了這樣的任務。這種解決方案優於ghostdog74的優點是,它可以自動轉換任意長度的十六進制字符串。使用xargs是因爲printf不從標準輸入中讀取數據。

+0

或直接輸入:printf'\ x5a' – Vouze 2014-07-30 08:36:04

+0

@Vouze我的答案的哪個方面是您的評論應該解決的問題? – josch 2014-07-30 12:04:34

+1

該死的,我知道這是在3年後的複雜答案,但我沒有線索xxd存在。由於我現在遇到的問題,我一直需要它......恆定的十六進制字節字符串從調試器轉儲。是的,@Vouze的評論是該死的毫無意義。 – 2014-09-02 13:39:20

10

你可以通過回聲而不是其他的東西。不要忘記添加「-n」,否則您將自動獲得換行符:

echo -n -e "\x5a" 
+1

不回答上面提到的問題,但回答了當我在這裏搜索谷歌發送給我的問題:-)(btw。發送輸出到| hexdump -C有助於識別不需要的換行符等) – JepZ 2015-05-09 13:32:12

0

GNU awk 4。1

awk -niord '$0=chr("0x"RT)' RS=.. ORS= 

請注意,如果您回顯到這一點,就會產生一個額外的空字節

$ echo 595a | awk -niord '$0=chr("0x"RT)' RS=.. ORS= | od -tx1c 
0000000 59 5a 00 
      Y Z \0 

而是用printf

$ printf 595a | awk -niord '$0=chr("0x"RT)' RS=.. ORS= | od -tx1c 
0000000 59 5a 
      Y Z 

還要注意的是GNU AWK默認情況下會產生UTF-8

$ printf a1 | awk -niord '$0=chr("0x"RT)' RS=.. ORS= | od -tx1 
0000000 c2 a1 

如果你ar È處理ASCII外的字符,並且你將是編碼所得到的字符串 Base64的,則可以禁用UTF-8與-b

echo 5a | sha256sum | awk -bniord 'RT~/\w/,$0=chr("0x"RT)' RS=.. ORS= 
1

這裏是一個純bash腳本(如printf是一個bash內建) :

#warning : spaces do matter 
die(){ echo "[email protected]" >&2;exit 1;} 

p=48656c6c6f0a 

test $((${#p} & 1)) == 0 || die "length is odd" 
p2=''; for ((i=0; i<${#p}; i+=2));do p2=$p2\\x${p:$i:2};done 
printf "$p2" 

如果bash已經運行,這應該比啓動新進程的任何其他解決方案都快。

+0

略短:' for((i = 0; i <$ {#p}; i + = 2)); do p2 + = \\ x $ {p:$ i:2}; done' – starfry 2014-11-10 18:45:14

7

猛砸一個班輪

echo -n "5a" | while read -N2 code; do printf "\x$code"; done 
+0

這似乎並不適用於多線程,字節消息...當我運行 'echo -n「0102abcd」|同時讀取-n 2代碼;做printf「\ x $ code」;完成| hexdump' 產量 '0201 cdab' – 2016-03-02 19:15:07

+1

@約翰鋼似乎hexdump都顯示數據作爲默認在十六進制數字字。試試這個'echo -n「0102abcd」|同時讀取-n 2代碼;做printf「\ x $ code」;完成| hexdump -e'/ 1「%02x」''' – user3132194 2016-03-03 05:28:32

1

DC可以數字基地之間進行轉換:

$ echo 5a | (echo 16i; tr 'a-z' 'A-Z'; echo P) | dc 
Z$ 
2

一些python3單行與任何字節數工作。

解碼十六進制(含strip,所以它的確定有標準輸入一個換行符):

$ echo 666f6f0a | python3 -c "import sys, binascii; sys.stdout.buffer.write(binascii.unhexlify(input().strip()))" 
foo 

編碼(十六進制)

$ echo foo | python3 -c "import sys, binascii; print(binascii.hexlify(sys.stdin.buffer.read()).decode())" 
666f6f0a 
+0

只需在解碼hex時使用print命令,你就可以看到ctrl chars,null chars,e.t.c .. 'echo 666f6f0a62617200 | python3 -c「import sys,binascii; print(binascii.unhexlify(input()))」'OUTPUT: 'b'foo \ nbar \ x00'' – gaoithe 2016-01-12 12:03:23

相關問題