シェルハウツー:いくつかの追加データを含む複数のバイナリデータファイル(jpg)を1つのファイルとして保存してから再度分割します。

シェルハウツー:いくつかの追加データを含む複数のバイナリデータファイル(jpg)を1つのファイルとして保存してから再度分割します。

限られたコンピューティングパフォーマンス(fritzbox)と機能(busybox)を備えたシステムとJPGファイルを転送できるWebカメラがあります。今、私は5秒ごとにJPGファイルをダウンロードして保存し(この問題はありません)、後でWebサーバーを介してストリーミングする
方法(シェルスクリプトベース)を探しています。wget

すべてを設定しましたが、いくつかの問題が発生しました。システムが非常に遅くなり、1つのフォルダにJPGファイルが多すぎて(複数のフォルダに分割しても)1つのファイル(echo、、、cat...)に書き込むことを検討しました。 )後でもう一度抽出します(sed、、awk)。
シェルスクリプトはバイナリデータを処理するのには適していないため、 "echo"および "cat"コマンドは読みやすいjpgファイルを生成しないため失敗します。

JPGファイルをwget一時ファイルまたは変数としてダウンロードします。現在、私はcat各新しいJPGを共通ファイルに保存し、改行なしで再び表示される一意の文字列(「--myboundary」など)に区切ります。

これで、すべてのJPGを含むこの汎用ファイルから単一のjpgを抽出するにはどうすればよいですか?試してみましたが、awk悪い結果が出ました。

答え1

再起動できる場合はそれを使用してくださいtar。次のオプションを持つ「追加モード」がありますr

$ ls t.tar
ls: cannot access t.tar: No such file or directory
$ tar rvf t.tar t.c
t.c
$ tar rvf t.tar t.cpp
t.cpp
$ tar tf t.tar
t.c
t.cpp

(ご覧のように、追加モードを使用するためにtarファイルが存在する必要はありません。あなたの場合は使いやすいでしょう。)

完全なGNU tar実装がない場合は、awk同様のものを使用してマージされたファイルを並べ替えることができるはずです。これスタックオーバーフローポスト):

awk -vRS="--myboundary" '{ print $0 > NR".jpg" }' yourfile

1.jpgこれにより、名前などのファイルが生成されます。2.jpg問題:\nファイルの末尾にハッシュ文字を追加してください。ご使用の環境にそのファイルがあると仮定すると、次のようにファイルを変更できます
truncatestat

truncate -s $(( $(stat -c %s 1.jpg) - 1 )) 1.jpg

そのファイルが見つからない場合は、statファイル名を見つけるには別のものが必要です(構文解析ls 可能ファイル名が正常であることがわかっているので、この場合は問題ありません。そうでない場合は、これを達成するためにまたはを使用truncateできます。または、末尾を無視できます。とにかく画像が正しく表示される可能性が高いです。ddheadtail
\n

デモ:

$ cp orig.1.png blob
$ echo -n "HELLOHELLO" >> blob 
$ cat orig.2.png >> blob 
$ ls -l
total 36
-rw-r--r-- 1 test test 14916 Dec 30 19:42 blob
-rw-r--r-- 1 test test  5735 Dec 30 19:41 orig.1.png
-rw-r--r-- 1 test test  9171 Dec 30 19:41 orig.2.png

$ awk -vRS="HELLOHELLO" '{print $0 > "new."NR".png"}' blob
$ ls -l
total 56
-rw-r--r-- 1 test test 14916 Dec 30 19:42 blob
-rw-r--r-- 1 test test  5736 Dec 30 19:43 new.1.png
-rw-r--r-- 1 test test  9172 Dec 30 19:43 new.2.png
-rw-r--r-- 1 test test  5735 Dec 30 19:41 orig.1.png
-rw-r--r-- 1 test test  9171 Dec 30 19:41 orig.2.png

$ for i in new* ; do truncate -s $(( $(stat -c %s $i) - 1 )) $i ; done
$ ls -l
total 56
-rw-r--r-- 1 test test 14916 Dec 30 19:42 blob
-rw-r--r-- 1 test test  5735 Dec 30 19:43 new.1.png
-rw-r--r-- 1 test test  9171 Dec 30 19:43 new.2.png
-rw-r--r-- 1 test test  5735 Dec 30 19:41 orig.1.png
-rw-r--r-- 1 test test  9171 Dec 30 19:41 orig.2.png
$ md5sum *.png
70718d7b9e717206b4a8455ea32b51ed  new.1.png
531099b9527f5fc2b623a3f724573ea9  new.2.png
70718d7b9e717206b4a8455ea32b51ed  orig.1.png
531099b9527f5fc2b623a3f724573ea9  orig.2.png

答え2

tarまたは類似のアーカイブ形式をほぼ再作成しようとしています。手動で行うことは、既存のツールを使用するよりも簡単になるとは思わないでください。

カスタムボーダーの使用に固執する場合(Jpegファイルの1つでボーダーが自然に表示される可能性があるため危険です)、改行で始めて終了するようにしてください。これにより処理が簡単になりますawk

各ファイルを個別に保持することをお勧めしますが、ディレクトリあたりのファイル数は、パフォーマンスに影響を与えないように小さい数に制限することをお勧めします。 5秒ごとに1つのファイル、日/時/分の入れ子構造は、最大366/60/20分岐を提供するため、パフォーマンスの面では問題ありません。

アーカイブを使用したいがBusybox tarにコマンドが不足している場合は、rN個のファイルをファイルシステムに保存してから、定期的に既存のファイルと一緒にアーカイブして履歴を整理できます。たとえば、100 ファイルごとにアーカイブするには、次のようにします。

set -- *
if [ $# -gt 100 ]; then
  set ../archives/*.tar
  eval "last=\${$#}"
  last=${last%[!0-9]}; last=${last##[!0-9]}
  tar cf ../archives/$((last+1)).tar -- *
  rm -- *
fi

関連情報