shell howto:将多个二进制数据文件(jpg)与一些附加数据保存到一个文件中,然后再次分开

shell howto:将多个二进制数据文件(jpg)与一些附加数据保存到一个文件中,然后再次分开

我有一个计算能力(fritzbox)和功能(busybox)有限的系统和一个网络摄像头,能够传输 JPG 文件。
现在我正在寻找一种方法(基于 shell 脚本)每 5 秒下载一次 JPG 文件,保存它们(这没有问题wget)并稍后通过网络服务器流式传输它们。

我设置了一切,但遇到了一些问题:由于系统变得非常慢,一个文件夹中有这么多 JPG 文件(即使我将它们分成几个文件夹),我考虑将它们写入一个文件(echocat,... )并稍后再次提取它们(sed, awk)。
现在,shell 脚本不太适合处理二进制数据,因此“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.jpg2.jpg问题:它\n在文件末尾添加了一个杂散符。
假设您有truncate并且stat在您的环境中,您可以使用以下方法修复这些文件:

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

如果你没有stat,你将需要其他东西来找出文件名(解析ls 可能在这种情况下没问题,因为你知道文件名是正常的)。如果没有truncate,您可以使用dd, 或者可能使用head或来实现这一点tail
或者您可以忽略尾随\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 文件中),请使其以换行符开始和结束。这将有利于处理awk

我建议将每个文件分开,但将每个目录的文件数量限制为足够小的数量,以免影响性能。每 5 秒一个文件,日/小时/分钟的嵌套结构给出的最大分支为 366/60/20,这在性能方面应该是可以的。

如果您想使用存档,并且考虑到 Busybox tar 中缺少命令r,您可以在文件系统中存储 N 个文件,然后定期使用现有文件进行存档并清理记录。例如,每 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

相关内容