NULLを使用して標準入力を希望の長さで埋める最良の方法

NULLを使用して標準入力を希望の長さで埋める最良の方法

次の要件があります。固定長のバイトに切り捨てる必要がある入力ストリームがあります。入力ストリームの長さを事前に知りません。ストリームの長さが設定された長さより小さい場合は、0バイトで埋めたいと思います。を使ってみましたが、truncate標準入力ではないファイルだけを処理できるようです。

TESTたとえば、入力ストリーム(stdin)があり、長さが10バイトになりたいとします。その後、出力ストリーム(stdout)はTEST\x00\x00\x00\x00\x00

これを明確にするために、例は小さな文字列を使用して行われましたが、結果は大規模ストリーム(メガバイトからギガバイトまで)でもうまくいくはずです。そして現在私が使用しているコンテナはUbuntuベースです。

ベストアンサー1

GNUの使用dd:

$ printf %s test | dd iflag=fullblock bs=10 status=none conv=sync count=1 | hexdump -C
00000000  74 65 73 74 00 00 00 00  00 00                    |test......|
0000000a

の場合、ightパディング(および切り捨て)引数拡張フラグ(パディング文字列の拡張などのエスケープシーケンスのフラグ)をzsh使用します。rp\0

$ string=test
$ printf %s ${(pr[10][\0])string} | hexdump -C
00000000  74 65 73 74 00 00 00 00  00 00                    |test......|
0000000a

しかし、10までパディングされることに注意してください。数値、10バイトではありません。multibyteこのオプションをオフにすると、これを変更できますset +o multibyte

$ string=tést
$ printf %s ${(pr[10][\0])string} | hexdump -C
00000000  74 c3 a9 73 74 00 00 00  00 00 00                 |t..st......|
0000000b
$ printf %s ${(pr[10][\0])string} | wc -mc
     10      11
$ set +o multibyte
$ printf %s ${(bpr[10][\0])string} | hexdump -C
00000000  74 c3 a9 73 74 00 00 00  00 00                    |t..st.....|
0000000a
$ printf %s ${(bpr[10][\0])string} | wc -mc
      9      10

これらのソリューションは、システムのRAM容量よりも大きいサイズでは拡張できません。

@ilkkachuがコメントで提案したように、大きなサイズの場合

{ printf %s test; cat /dev/zero; } | head -c 1000000000

より効率的です(標準ではありませんが、一般的で、head -c一度に1バイトを読み書きするよりもはるかに効率的です)。dd bs=1

ファイルに出力する場合は、リソース制限を使用して以下を切り捨てることもできます。

(
  ulimit -f 1048576 # KiB
  printf %s test
  cat /dev/zero
) > file

おすすめ記事