나는 당신이 이것을 할 수 있다고 생각하지 않습니다-확실하지 않고 당신이 요구하는 방식이 아닙니다. 문제는 아카이브의 압축 비율이 머리에서 꼬리까지 고르게 분포되지 않을 것입니다. 압축 알고리즘은 다른 부분보다 일부에 더 잘 적용됩니다. 그것이 작동하는 방식입니다. 따라서 압축 파일의 크기에 대한 분할을 고려할 수 없습니다.
무엇보다, 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
$line
printf
printf
lz4
dd
dd
read $line
lz4
각 반복에서 약 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
은 얼마나 걸립 니까?