-r
の追加 オプション (リバースモード) を xxd -b
に xxd は単にこれら 2 つのフラグの組み合わせをサポートしていないためです (-b
は無視されます)。 両方が指定されている場合)。代わりに、最初に自分でビットを 16 進数に変換する必要があります。たとえば、次のようになります:
( echo 'obase=16;ibase=2'; sed -Ee 's/[01]{4}/;\0/g' instructions.txt ) | bc | xxd -r -p > instructions.bin
完全な説明:
- 括弧内の部分は
bc
を作成します 脚本。まず、入力基数を 2 進数 (2) に、出力基数を 16 進数 (16) に設定します。その後、sed
コマンドはinstructions.txt
の内容を出力します 16 進数の 1 桁に相当する 4 ビットの各グループの間にセミコロンを挿入します。結果はbc
にパイプされます . - セミコロンは
bc
のコマンド区切り文字です であるため、スクリプトはすべての入力整数を出力するだけです (基数変換後)。 bc
の出力 通常のxxd -r -p
でファイルに変換できる 16 進数のシーケンスです。 .
出力:
$ hexdump -Cv instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011 ....
00000004: 00000010 11010001 00100000 10000011 .. .
00000008: 00000000 01110011 00000010 10110011 .s..
0000000c: 00000000 01110011 00000100 00110011 .s.3
00000010: 00000000 01110011 01100100 10110011 .sd.
00000014: 00000000 00000000 00000000 00010011 ....
1 と 0 の 32 ビット文字列を対応するバイナリに変換する oneliner:
$ perl -ne 'print pack("B32", $_)' < instructions.txt > instructions.bin
機能:
perl -ne
STDIN (instructions.txt
) で提供される入力ファイルの各行を反復処理します。 )pack("B32", $_)
32 ビットの文字列リスト ($_
これを STDIN から読み取っただけ)、それをバイナリ値に変換します (代わりに"b32"
を使用することもできます)。 降順のビット順ではなく、各バイト内で昇順のビット順が必要な場合。perldoc -f pack
を参照 詳細はこちら)print
次に、変換された値を STDOUT に出力し、それをバイナリ ファイルinstructions.bin
にリダイレクトします。
検証:
$ hexdump -Cv instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011 ....
00000004: 00000010 11010001 00100000 10000011 .. .
00000008: 00000000 01110011 00000010 10110011 .s..
0000000c: 00000000 01110011 00000100 00110011 .s.3
00000010: 00000000 01110011 01100100 10110011 .sd.
00000014: 00000000 00000000 00000000 00010011 ....
元の回答が間違っていました - xxd
-p
のどちらも受け入れられません または -r
-b
で ...
他の答えが実行可能であり、「別の方法」の利益のために "、次はどうですか:
入力
$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011
出力
$ hexdump -Cv < instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
Bash パイプライン:
cat instructions.txt \
| tr -d $'\n' \
| while read -N 4 nibble; do
printf '%x' "$((2#${nibble}))"; \
done \
| xxd -r -p \
> instructions.bin
cat
- 不要ですが、わかりやすくするために使用していますtr -d $'\n'
- 入力からすべての改行を削除read -N 4 nibble
- 正確に読むnibble
に 4× 文字 変数printf '%x' "$((2#${nibble}))"
ニブルをバイナリから 1× 16 進文字に変換します$((2#...))
- 指定された値を基数 2 (2 進数) から基数 10 (10 進数) に変換しますprintf '%x'
- 指定された値を基数 10 (10 進数) から基数 16 (16 進数) にフォーマットします
xxd -r -p
- 逆 (-r
) プレーン ダンプ (-p
) - 16 進数から生の 2 進数へ
パイソン:
python << EOF > instructions.bin
d = '$(cat instructions.txt | tr -d $'\n')'
print(''.join([chr(int(d[i:i+8],2)) for i in range(0, len(d), 8)]))
EOF
- 引用されていないヒアドキュメント (
<< EOF
) は、コンテンツを Python コードに取り込むために使用されます- 入力が大きくなると効率が悪い
cat
とtr
- クリーンな (1 行の) 入力を取得するために使用range(0, len(d), 8)
- 0 から文字列d
の末尾までの数字のリストを取得します 、一度に 8 倍の文字をステップ実行します。chr(int(d[i:i+8],2))
- 現在のスライスを変換 (d[i:i+8]
) 2 進数から 10 進数 (int(..., 2)
) )、そして生の文字 (chr(...)
) )[ x for y in z]
- リストの理解''.join(...)
- 文字のリストを単一の文字列に変換print(...)
- 印刷