나는 당신이 이것을 할 수 있다고 생각하지 않습니다-확실하지 않고 당신이 요구하는 방식이 아닙니다. 문제는 아카이브의 압축 비율이 머리에서 꼬리까지 고르게 분포되지 않을 것입니다. 압축 알고리즘은 다른 부분보다 일부에 더 잘 적용됩니다. 그것이 작동하는 방식입니다. 따라서 압축 파일의 크기에 대한 분할을 고려할 수 없습니다.
무엇보다, gzip단지 크기 만 4GB보다 큰 압축 파일의 원래 크기를 저장하는 지원하지 않습니다 - 그것을 처리 할 수 없습니다. 따라서 신뢰할 수있는 크기를 얻기 위해 아카이브를 쿼리 할 수 없습니다.
4 줄은 정말 쉽습니다. 4 파일-압축하지 않은 크기를 얻기 위해 먼저 아카이브를 추출하지 않고 안정적으로 고르게 배포 할 수있는 방법을 모르겠습니다. 내가 시도했기 때문에 당신이 할 수 있다고 생각하지 않습니다.
그러나 할 수있는 일은 분할 출력 파일의 최대 크기를 설정하고 파일이 항상 레코드 장벽에서 깨지는 지 확인하는 것입니다. 쉽게 할 수 있습니다. 다음은 gzip아카이브 를 추출하고 각 인수 를 압축 해제 / 재 압축 하기 위해 전달하기 전에 dd특정 count=$rpt인수를 사용 하여 명시 적 파이프 버퍼를 통해 내용을 파이핑하여 수행하는 작은 스크립트입니다 lz4. 또한 tee각 세그먼트의 마지막 네 줄을 stderr에 인쇄 하는 몇 가지 작은 파이프 트릭을 던졌습니다 .
( IFS= n= c=$(((m=(k=1024)*k)/354))
b=bs=354xk bs=bs=64k
pigz -d </tmp/gz | dd i$bs o$b |
while read -r line _$((n+=1))
do printf \\n/tmp/lz4.$n\\n
{ { printf %s\\n "$line"
dd count=$c i$b o$bs
}| tee /dev/fd/3|lz4 -BD -9 >/tmp/lz4.$n
} 3>&1| tail -n4 |tee /dev/fd/2 |
wc -c;ls -lh /tmp/[gl]z*
done
)
모든 입력을 처리 할 때까지 계속 진행됩니다. 그것은 그것을 얻을 수없는 백분율로 나누려고하지 않지만 대신 스플릿 당 최대 원시 바이트 수로 나눕니다. 어쨌든, 문제의 큰 부분은 아카이브가 너무 커서 아카이브에서 신뢰할 수있는 크기를 얻을 수 없다는 것입니다-당신이 무엇이든간에 다시하지 마십시오-4gbs 미만의 조각을 조각으로 만듭니다. , 아마도. 최소한이 작은 스크립트를 사용하면 압축되지 않은 바이트를 디스크에 쓰지 않고도이 작업을 수행 할 수 있습니다.
다음은 필수 사항을 제거한 짧은 버전입니다. 모든 보고서에 추가되지는 않습니다.
( IFS= n= c=$((1024*1024/354))
pigz -d | dd ibs=64k obs=354xk |
while read -r line _$((n+=1))
do { printf %s\\n "$line"
dd count=$c obs=64k ibs=354xk
} | lz4 -BD -9 >/tmp/lz4.$n
done
) </tmp/gz
그것은 첫 번째와 똑같은 일을합니다. 대부분 그것에 대해 할 말이 없습니다. 또한 혼란이 적기 때문에 진행 상황을 쉽게 볼 수 있습니다.
IFS=것은 단지 하나 개 처리하는 것입니다 read반복 당 라인. 우리는 read하나 때문에 우리는 때 입력이 종료 종료 우리의 루프가 필요합니다. 이것은 레코드 크기 에 따라 다릅니다. 예를 들어 354 바이트입니다. gzip테스트하기 위해 임의의 데이터로 4 + gb 아카이브를 만들었 습니다.
무작위 데이터는 다음과 같이 얻었습니다.
( mkfifo /tmp/q; q="$(echo '[1+dPd126!<c]sc33lcx'|dc)"
(tr '\0-\33\177-\377' "$q$q"|fold -b144 >/tmp/q)&
tr '\0-\377' '[A*60][C*60][G*60][N*16][T*]' | fold -b144 |
sed 'h;s/^\(.\{50\}\)\(.\{8\}\)/@N\1+\2\n/;P;s/.*/+/;H;x'|
paste "-d\n" - - - /tmp/q| dd bs=4k count=kx2k | gzip
) </dev/urandom >/tmp/gz 2>/dev/null
...하지만 이미 데이터와 모든 것을 가지고 있기 때문에 그것에 대해 너무 걱정할 필요가 없습니다. 솔루션으로 돌아 가기 ...
기본적으로 pigz는 압축보다 약간 빠른 속도로 zcat압축되지 않은 것처럼 압축되지 않은 스트림과 dd출력 블록으로 출력되는 버퍼를 354 바이트의 배수로 출력합니다. 루프 것 는 것이다 입력이 아직 도착하는지 테스트로 각 반복 번 이후 에 서로가 이전 블록을 읽어라고 354 바이트의 배수에서 구체적으로 크기 - 버퍼링과 동기화 프로세스 - 기간 동안. 초기 단계로 인해 반복마다 하나의 짧은 읽기가 발생 하지만 수집기 프로세스 에서 인쇄하기 때문에 중요하지 않습니다 .read$lineprintfprintflz4ddddread $linelz4
각 반복에서 약 1GB의 압축되지 않은 데이터를 읽고 인스 트림에서 약 650Mb 정도로 압축하도록 설정했습니다. lz4다른 유용한 압축 방법보다 훨씬 빠릅니다. 대기하지 않기 때문에 여기에서 선택한 이유입니다. xz그래도 실제 압축에서 훨씬 더 나은 작업을 수행 할 것입니다. lz4그러나 한 가지 중요한 점은 RAM 속도에 가깝게 압축을 풀 lz4수 있다는 것입니다. 즉, 어쨌든 메모리에 기록 할 수있는 것처럼 빨리 압축을 풀 수 있습니다 .
큰 것은 반복마다 몇 가지 보고서를 수행합니다. 두 루프 모두 dd전송 된 원시 바이트 수와 속도 등에 대한 보고서를 인쇄 합니다. 큰 루프는 사이클 당 마지막 4 줄의 입력과 동일한 바이트 수를 인쇄 한 다음 아카이브를 ls작성하는 디렉토리를 인쇄합니다 lz4. 다음은 두 단계의 출력입니다.
/tmp/lz4.1
2961+1 records in
16383+1 records out
1073713090 bytes (1.1 GB) copied, 169.838 s, 6.3 MB/s
@NTACGTANTTCATTGGNATGACGCGCGTTTATGNGAGGGCGTCCGGAANGC+TCTCTNCC
TACGTANTTCATTGGNATGACGCGCGTTTATGNGAGGGCGTCCGGAANGCTCTCTNCCGAGCTCAGTATGTTNNAAGTCCTGANGNGTNGCGCCTACCCGACCACAACCTCTACTCGGTTCCGCATGCATGCAACACATCGTCA
+
I`AgZgW*,`Gw=KKOU:W5dE1m=-"9W@[AG8;<P7P6,qxE!7P4##,Q@c7<nLmK_u+IL4Kz.Rl*+w^A5xHK?m_JBBhqaLK_,o;p,;QeEjb|">Spg`MO6M'wod?z9m.yLgj4kvR~+0:.X#(Bf
354
-rw-r--r-- 1 mikeserv mikeserv 4.7G Jun 16 08:58 /tmp/gz
-rw-r--r-- 1 mikeserv mikeserv 652M Jun 16 12:32 /tmp/lz4.1
/tmp/lz4.2
2961+1 records in
16383+1 records out
1073713090 bytes (1.1 GB) copied, 169.38 s, 6.3 MB/s
@NTTGTTGCCCTAACCANTCCTTGGGAACGCAATGGTGTGANCTGCCGGGAC+CTTTTGCT
TTGTTGCCCTAACCANTCCTTGGGAACGCAATGGTGTGANCTGCCGGGACCTTTTGCTGCCCTGGTACTTTTGTCTGACTGGGGGTGCCACTTGCAGNAGTAAAAGCNAGCTGGTTCAACNAATAAGGACNANTTNCACTGAAC
+
>G-{N~Q5Z5QwV??I^~?rT+S0$7Pw2y9MV^BBTBK%HK87(fz)HU/0^%JGk<<1--7+r3e%X6{c#w@aA6Q^DrdVI0^8+m92vc>RKgnUnMDcU:j!x6u^g<Go?p(HKG@$4"T8BWZ<z.Xi
354
-rw-r--r-- 1 mikeserv mikeserv 4.7G Jun 16 08:58 /tmp/gz
-rw-r--r-- 1 mikeserv mikeserv 652M Jun 16 12:32 /tmp/lz4.1
-rw-r--r-- 1 mikeserv mikeserv 652M Jun 16 12:35 /tmp/lz4.2
zcat file > /dev/null은 얼마나 걸립 니까?