「\x00」バイトを含むバイナリストリームの編集

「\x00」バイトを含むバイナリストリームの編集

シェルツールのみを使用してNULL(0x00文字)を含むバイナリストリームを編集し、出力ストリームで0x00文字を保持するにはどうすればよいですか?

編集するには、以下のように指定された位置の1文字を別の文字(以下の例では「|」文字)に置き換える必要があります。

dd ibs=1 skip=$offset count=$reglen status=none if=$ARQ |
        sed 's/./\|/2' |
        sed 's/./\|/5' #| more replacements....

ただし、sedは置き換える前に '\ 0x00'文字をすべて削除します。

編集 - @George Vasiliouのテストを使用して、私の環境でsedの動作を表示します。

$ echo -e "lineA\nlineB\nlineC" | tr '\n' '\0' | od -t x1
0000000 6c 69 6e 65 41 00 6c 69 6e 65 42 00 6c 69 6e 65
0000020 43 00
0000022

$ echo -e "lineA\nlineB\nlineC" | tr '\n' '\0' | sed 's/./|/5' | od -t x1
0000000 6c 69 6e 65 7c 6c 69 6e 65 42 6c 69 6e 65 43
0000017

私の環境はAIX 7.1で、sedにはGNUバージョンはありません。

ベストアンサー1

sedテキスト便利です。それは適用されますテキスト行(改行で区切られた非NUL文字(バイトではない)の制限された長さのシーケンス)。

2番目5番目を変更したい場合 バイトバイトシーケンスですが、いくつかの理由で動作しません。

  • sedテキストに適用されます。入力にNUL文字が含まれていて、改行で終わらず、2つの改行の間にLINE_MAXバイト以上があり、有効な文字を形成しないバイトシーケンスが含まれていると(実装に応じて)sedまったく機能しません。 (GNUにはsedこれらの制限はほとんどありません。)
  • 対応するバイナリ入力が有効なテキストを形成しても、バイト以外の文字.と一致するため、複数のバイトが一致する可能性があります。
  • sedコードはそれぞれに対して実行されるためワイヤー入力の2番目と5番目の文字は、入力全体の2番目と5番目の文字ではなく、各行の2番目と5番目の文字を変更します。

入力をNULバイト制限や長さ制限なしで任意のバイト配列として扱うには、次のようにしますperl

 dd.... | perl -0777 -pe 'for $o (1, 4) {substr($_, $o, 1) = "|"}'

例:

$ printf 'a\0b\0cd' |
>   perl -0777 -pe 'for $o (1, 4) {substr($_, $o, 1) = "|"}' |
>   od -Ax -tx1 -tc
000000  61  7c  62  00  7c  64
         a   |   b  \0   |   d
000006

vimあるいは、ヘルパーを使用して中間テキスト表現を使用することもできますxxd

dd... | xxd -p | sed '1s/../7c/2;1s/../7c/5' | xxd -p -r

xxd -pデフォルトでは、16進ダンプは1行に60文字で提供されます。上記の最初の行の2番目と5番目の2桁の16進数字を7cASCII数字に置き換えました|

おすすめ記事