bashスクリプトを使用してバイナリファイルの内容を読み取るには?

bashスクリプトを使用してバイナリファイルの内容を読み取るには?

文字を読んだ後、固定長文字列(ファイル内でnullで終わらずに前の文字で長さが指定されています)を読みたいと思います。

Bashスクリプトでこれをどのように実行できますか?後処理を実行できるように文字列変数をどのように定義しますか?

ベストアンサー1

シェルユーティリティを引き続き使用するには、head複数のバイトを抽出し、odバイトを数値に変換するために使用できます。

export LC_ALL=C    # make sure we aren't in a multibyte locale
n=$(head -c 1 | od -An -t u1)
string=$(head -c $n)

しかし、動作しませんバイナリデータの場合。 2つの質問があります。

  • コマンド置換$(…)バー最後の改行文字コマンド出力から。非常に簡単な解決策があります。出力が改行以外の文字で終わっていることを確認し、その文字を削除します。

    string=$(head -c $n; echo .); string=${string%.}
    
  • ほとんどのシェルと同様に、Bashは処理にうまくいきません。ヌルバイト。 Bash 4.1以降、コマンド置換の結果からヌルバイトが単純に削除されます。 Dash 0.5.5 と pdksh 5.2 は同じ動作を持ち、ATT ksh は最初の null バイトで読み出しを停止します。通常、シェルとそのユーティリティはバイナリファイルの処理には適していません。 (ヌルバイトをサポートするように設計されたZshは例外です。)

バイナリデータがある場合は、PerlやPythonなどの言語に切り替える必要があります。

<input_file perl -e '
  read STDIN, $c, 1 or die $!;    # read length byte
  $n = read STDIN, $s, ord($c);   # read data
  die $! if !defined $n;
  die "Input file too short" if ($n != ord($c));
  # Process $s here
'
<input_file python -c '
  import sys
  n = ord(sys.stdin.read(1))      # read length byte
  s = sys.stdin.read(n)           # read data
  if len(s) < n: raise ValueError("input file too short")
  # Process s here
'

おすすめ記事