쉘 하우투: 일부 추가 데이터가 포함된 여러 바이너리 데이터 파일(jpg)을 하나의 파일로 저장한 다음 다시 분리합니다.

쉘 하우투: 일부 추가 데이터가 포함된 여러 바이너리 데이터 파일(jpg)을 하나의 파일로 저장한 다음 다시 분리합니다.

제한된 컴퓨팅 성능(fritzbox)과 기능(busybox)을 갖춘 시스템과 JPG 파일을 전송할 수 있는 웹캠이 있습니다. 이제 나는 5초마다 JPG 파일을 다운로드하고 저장한 다음(이 문제는 없음 ) 나중에 웹 서버를 통해 스트리밍하는
방법(셸 스크립트 기반)을 찾고 있습니다 .wget

모든 것을 설정했는데 몇 가지 문제가 발생했습니다. 시스템이 매우 느려지고 한 폴더에 JPG 파일이 너무 많아서 (여러 폴더로 나누어도) 하나의 파일 ( 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 파일 중 하나에서 테두리가 자연스럽게 나타날 수 있으므로 위험함) 줄 바꿈으로 시작하고 끝나도록 만드세요. 이렇게 하면 처리가 쉬워집니다 awk.

각 파일을 별도로 유지하는 것이 좋지만 디렉터리당 파일 수는 성능에 영향을 주지 않을 만큼 작은 수로 제한하는 것이 좋습니다. 5초마다 하나의 파일, 일/시/분의 중첩 구조는 최대 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

관련 정보