文字を読んだ後、固定長文字列(ファイル内で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
'