一行代码解决此问题:
data=$(cat file.in); echo $(printf '%x\n' "$((2#$data))") | xxd -r -p > file.out
问题在于printf似乎有一个字符限制,可以通过将数据分成块使之可被处理,例如每8个字节一组(在我的Ubuntu 16.04.7上)。
一种解决方法是逐个字符(字节序列)或从文件中逐行循环。
data=$(cat file.in); for byte in $data; do echo $(printf '%x\n' "$((2#$byte))"); done | xxd -r -p
不需要将其转换为八进制或在分离单词之前逐行读取。
字典/数据库/数组可能是另一种但较慢的解决方案(如果你有足够的内存或不想将数据存储在文件中):
D2B=(01000001 01110010 01100101 01101110 00100111 01110100 00100000 01111001 01101111 01110101 00100000 01100001 00100000 01101100 01101001 01110100 01110100 01101100 01100101 00100000 01110011 01101000 01101111 01110010 01110100 00100000 01100110 01101111 01110010 00100000 01100001 00100000 01110011 01110100 01101111 01110010 01101101 00100000 01110100 01110010 01101111 01101111 01110000 01100101 01110010 00111111 00001101 00001010);
count=${#D2B[@]};
run='D2C=('${D2B[@]}'); for word in {0..'$count'}; do echo -n $(printf '
echo "$run" | bash | xxd -r -p
或者将字符串解决方案传递给数组以获得更快的响应:
dat="01000001 01110010 01100101 01101110 00100111 01110100 00100000 01111001 01101111 01110101 00100000 01100001 00100000 01101100 01101001 01110100 01110100 01101100 01100101 00100000 01110011 01101000 01101111 01110010 01110100 00100000 01100110 01101111 01110010 00100000 01100001 00100000 01110011 01110100 01101111 01110010 01101101 00100000 01110100 01110010 01101111 01101111 01110000 01100101 01110010 00111111 00001101 00001010";
count=$(echo $dat ^| wc -w);
run='D2C=('$dat'); for word in {0..'$count'}; do echo -n $(printf '%x' "$((2#${D2C[$word]}))"); done;';
echo "$run" | bash | xxd -r -p
或者
仅字符串解决方案(无数组):
dat="01000001 01110010 01100101 01101110 00100111 01110100 00100000 01111001 01101111 01110101 00100000 01100001 00100000 01101100 01101001 01110100 01110100 01101100 01100101 00100000 01110011 01101000 01101111 01110010 01110100 00100000 01100110 01101111 01110010 00100000 01100001 00100000 01110011 01110100 01101111 01110010 01101101 00100000 01110100 01110010 01101111 01101111 01110000 01100101 01110010 00111111 00001101 00001010";
count=$(echo $dat ^| wc -w);
run='D2C="'$dat'"; for word in {0..'$count'}; do byte=${D2C:$((word+8*word)):8}; echo -n $(printf '%x' "$((2#$byte))"); done;';
echo "$run" | bash | xxd -r -p
在Ubuntu 16.04.7上进行了测试